CSS 中的伪类和伪元素是两组非常强大但也容易混淆的选择器。它们的核心区别可以用一句话概括:
伪类是给“真实存在的元素”添加特定的“状态”;而伪元素是在页面上凭空“捏造”出一个原本不存在的虚拟元素。
下面是它们的区别、语法规范以及常见的应用场景。
核心区别与语法规范
| 特性维度 | 伪类 (Pseudo-classes) | 伪元素 (Pseudo-elements) |
|---|---|---|
| 核心作用 | 选中元素的特定状态或特定位置 | 创建并选中一个虚拟的、不存在的元素 |
| 是否改变DOM | 否(仅改变样式,不增加节点) | 否(在CSS渲染层生成虚拟盒子,HTML中依然没有) |
| 语法标识 | 单冒号 : | 双冒号 :: (CSS3规范,用于区分伪类) |
| 典型代表 | :hover, :first-child, :checked | ::before, ::after, ::first-line |
关于冒号的补充说明:
在 CSS2 时代,伪类和伪元素都使用单冒号。CSS3 为了严格区分两者,规定伪元素必须使用双冒号 ::。不过,为了向下兼容,现代浏览器对 :before 和 :after 这类老牌伪元素依然支持单冒号写法,但建议在日常开发中遵循规范,使用双冒号。
伪类 (Pseudo-classes) 的应用场景
伪类就像是一个“条件触发器”,当元素满足某个条件(如被鼠标悬停、处于特定位置)时,样式才会生效。
- 用户交互状态:
最常用的场景,无需 JavaScript 就能实现基础的交互反馈。
/* 鼠标悬停在按钮上时变色 */ button:hover { background-color: #007bff; } /* 输入框获得焦点时改变边框 */ input:focus { border-color: blue; } /* 链接被点击激活的瞬间 */ a:active { color: red; } - 文档结构与位置:
根据元素在 HTML 树中的位置来精准打击,省去很多多余的 class 命名。
/* 选中列表的第一个子元素 */ li:first-child { font-weight: bold; } /* 选中表格的偶数行,实现斑马纹效果 */ tr:nth-child(even) { background-color: #f2f2f2; } /* 选中没有子元素的空 div */ div:empty { display: none; } - 表单验证状态:
配合 HTML5 表单验证,给用户直观的视觉提示。
/* 输入内容符合格式要求时显示绿色边框 */ input:valid { border-color: green; } /* 输入内容不符合要求时显示红色边框 */ input:invalid { border-color: red; } /* 复选框被勾选时改变标签颜色 */ input[type="checkbox"]:checked + label { color: green; }
伪元素 (Pseudo-elements) 的应用场景
伪元素就像是 CSS 的“影分身术”,可以在不污染 HTML 结构的前提下,凭空创造出装饰性的内容或选中元素的某一部分。
- 创造虚拟装饰元素 (
::before和::after): 这是伪元素最强大的功能,常用于添加纯装饰性的图标、文字或清除浮动。注意:使用它们时必须设置content属性(哪怕为空字符串"")。/* 在每个外部链接后面添加一个箭头图标 */ a[href^="http"]::after { content: " \2197"; /* Unicode 箭头字符 */ font-size: 0.8em; } /* 给标题前面加一根装饰竖线 */ h2::before { content: ""; display: inline-block; width: 4px; height: 20px; background-color: #007bff; margin-right: 10px; } /* 经典的清除浮动 (Clearfix) 方案 */ .clearfix::after { content: ""; display: table; clear: both; } - 选中元素的特定排版部分:
用于实现类似 Word 文档中的首字下沉等排版效果。
/* 让段落的首字母放大并加粗(首字下沉) */ p::first-letter { font-size: 2em; font-weight: bold; float: left; } /* 让段落的第一行文字变为蓝色 */ p::first-line { color: blue; } - 改变用户交互的默认样式:
定制用户在网页上操作时的默认视觉体验。
/* 自定义用户用鼠标选中文字时的背景色和字体颜色 */ ::selection { background-color: gold; color: black; } /* 改变输入框占位符文字的样式 */ input::placeholder { color: #999; font-style: italic; }
总结来说,需要根据状态(如悬停、点击)或位置(如第一个、偶数个)来改变样式时,请使用伪类;当你需要凭空添加装饰性内容,或者精准控制元素内部的某一部分(如首字母)时,请使用伪元素。