在 CSS 中,:before 和 :after 是我们常用的伪元素(Pseudo-elements),它们允许我们在不修改 HTML 的前提下,为元素添加额外的样式内容。但你是否注意过它们有时写成 ::before 和 ::after?这两种写法有什么区别呢?
本文将带你深入了解单冒号和双冒号的语法差异、历史演变及实际使用建议。
📌 一、基本概念对比
| 写法 | 类型 | 含义说明 |
|---|---|---|
:before | 单冒号 | CSS2.1 中定义的伪元素语法 |
::before | 双冒号 | CSS3 中推荐使用的伪元素语法 |
:after | 单冒号 | CSS2.1 中定义的伪元素语法 |
::after | 双冒号 | CSS3 中推荐使用的伪元素语法 |
🧩 二、单冒号 vs 双冒号的区别
✅ 1. 语法标准的演进
- 在 CSS2.1 中,伪元素使用的是单冒号语法,如
:before、:after; - 到了 CSS3 规范,为了区分伪类(pseudo-classes) 和伪元素(pseudo-elements),W3C 引入了双冒号语法:
::before::after::first-line::selection等
🔍 目的:让开发者更清晰地区分“伪类”和“伪元素”。
✅ 2. 功能上完全相同
无论是 :before 还是 ::before,它们的功能是一样的:
- 都可以插入内容(通过
content属性); - 都不会出现在 DOM 中;
- 都支持设置样式;
- 都是 inline 元素,默认内联显示;
示例代码:
/* 双冒号写法 */
.box::before {
content: "★";
color: red;
}
/* 单冒号写法 */
.box:before {
content: "★";
color: red;
}
两种写法在现代浏览器中都有效,效果完全一致。
📌 三、为什么会有这种变化?
✅ 区分伪类和伪元素
- 伪类(pseudo-class):用于表示元素的某种状态,如:
:hover:active:nth-child()
- 伪元素(pseudo-element):用于操作元素的内容部分或特定部分,如:
::before::after::first-letter
使用双冒号有助于一眼识别出这是“伪元素”,而不是“伪类”。
📈 四、兼容性与使用建议
| 特性 | :before / :after | ::before / ::after |
|---|---|---|
| 支持 CSS2.1 | ✅ | ❌ |
| 支持 CSS3+ | ✅ | ✅ |
| 推荐写法 | ❌(旧版) | ✅(新版、语义更清晰) |
| 实际功能 | 完全一致 | 完全一致 |
✅ 使用建议:
- 如果你的项目需要兼容老版本浏览器(如 IE6~IE8),可以继续使用单冒号;
- 在现代开发中,推荐使用双冒号
::before和::after,以符合规范并提升代码可读性; - 多数 CSS 预处理器(如 Sass、Less)也默认输出双冒号语法;
- Linter 工具(如 Stylelint)也会提示使用双冒号写法。
💡 五、伪元素的典型应用场景
| 场景描述 | 示例代码 |
|---|---|
| 添加装饰性图标 | .icon::before { content: "✨"; } |
| 清除浮动 | .clearfix::after { clear: both; display: block; content: ""; } |
| 文字高亮效果 | ::selection { background-color: yellow; } |
| 自定义列表项符号 | ul li::before { content: "•"; margin-right: 5px; } |
| 创建工具提示、箭头等图形结构 | 结合 border、transform 创建各种形状 |