跳到主要内容

伪元素和伪类的区别和作用

面试速答(30 秒版 TL;DR)

  • 伪类(pseudo-class):选中“已有元素”的某种状态/结构,例如 :hover:focus:nth-child(...)
  • 伪元素(pseudo-element):表示元素的“某一部分”或“生成的虚拟盒子”,例如 ::before::after::first-line
  • 语法上通常用 :(伪类)和 ::(伪元素)区分;现代规范推荐伪元素用双冒号。

对比表(面试最常用)

维度伪类 :xxx伪元素 ::xxx
作用对象已存在的元素元素的一部分/生成内容
典型用途交互状态、结构筛选装饰、分隔、首行/占位符/列表 marker
是否是 DOM 节点是(选中的仍是 DOM 元素)否(生成的渲染盒子,不是 DOM)
常见示例:hover:focus:nth-child:not::before::after::placeholder::marker

常见伪类(会举例即可)

  • 交互::hover:active:focus:focus-visible
  • 结构::first-child:last-child:nth-child(2n)
  • 逻辑::not(...):is(...):where(...)
  • 关系::has(...)(用于“父级选择”,但兼容性要评估)

常见伪元素(面试常考)

  • ::before / ::after:生成装饰性盒子(需要 content
  • ::first-line / ::first-letter:首行/首字样式
  • ::placeholder:输入框占位符
  • ::marker:列表项标记
  • ::selection:选中文本的样式

典型题 & 标准答法

Q1:::before/::after 为什么经常要写 content: ""

:因为伪元素的内容来自 content,没 content 往往就不会生成可见的伪元素盒子;content: "" 常作为“生成一个可样式化盒子”的开关。

Q2::before::before 有什么区别?

:历史上 CSS2.1 时代用单冒号写伪元素;现代规范推荐伪元素用双冒号以区分伪类。工程里一般写 ::before/::after,兼容性也没问题。可参考:::before / ::after 文档

Q3:伪元素能承载业务关键文案/交互吗?

:不建议。伪元素不是 DOM 节点,可访问性与交互能力有限,关键内容应放真实 DOM,伪元素更适合装饰。


易错点/坑

  • 把伪元素当成 DOM:querySelector('::before') 找不到它。
  • 伪元素做重要文本:屏幕阅读器支持不一致,容易影响无障碍。
  • 伪类/伪元素权重记错:伪类通常计入 class 级别,伪元素通常计入元素级别(更完整见:权重与层叠)。

速记要点(可背诵)

  • 伪类选“状态/结构”,伪元素选“部位/生成盒子”;伪元素常配 content;重要内容放真实 DOM。