伪元素和伪类的区别和作用
面试速答(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。