应使用双冒号::before,因其是CSS3标准,明确标识伪元素以提升可维护性;单冒号:before仅用于兼容已淘汰的IE8,现代项目须统一用::before。

单冒号 :before 是 CSS2 遗留写法,不是错误,但语义模糊
早期 CSS2 没有严格区分“状态筛选”和“内容生成”,所以 :before 和 :hover 都用单冒号。这导致开发者很难一眼分辨 :first-child(伪类)和 :before(伪元素)本质不同。CSS3 引入双冒号就是为解决这个混淆——::before 明确表示“这里在生成新内容”,而 :hover 仍保留单冒号,因为它只描述状态。
双冒号 ::before 是 CSS3 标准,现代项目应默认使用
CSS3 规范强制要求伪元素用双冒号,目的是提升可维护性。浏览器实现上,Chrome 4+、Firefox 3.5+、Safari 4+、Edge 12+、Opera 10+ 全部支持 ::before 和 ::after。即使你写 :before,现代浏览器也会兼容解析,但这属于向后兼容行为,不是推荐实践。
- 团队协作时,统一用
::before能减少新人误把:first-line当成伪类的困惑 - 代码审查中,看到单冒号伪元素容易触发质疑:“这是故意兼容 IE8?还是没注意规范?”
- 某些 CSS 工具链(如 stylelint)默认警告
:before写法,需额外配置关闭
IE8 及更早版本是唯一必须用单冒号的场景
IE8 只识别 :before,不支持 ::before;且它对 content 的支持极弱(比如不能用 url() 插入图片)。但截至 2026 年,IE8 全球使用率已低于 0.02%,绝大多数项目无需再为它妥协。若真要兼容:
- 不要混用:全项目统一用
:before,避免部分地方双冒号、部分单冒号 - 避免依赖 IE8 不支持的特性,例如
content: url(…)或display: flex在伪元素上 - 检查构建工具是否自动降级——PostCSS 的
autoprefixer不处理伪元素冒号,需手动替换
伪元素不生效?先确认标签是否支持 ::before/::after
::before 和 ::after 只对**能包含子节点的元素**有效。像 <img>、<input>、<iframe> 这类 void 元素或替换元素,浏览器根本不允许插入生成内容。常见表现是样式写了但完全不渲染。
立即学习“前端免费学习笔记(深入)”;
- 检查目标元素是否为块级容器(如
<div>、<p>、<span>),<span>默认 inline,需加display: inline-block或block才能稳定显示content -
content属性不可省略:哪怕只是空字符串content: "",缺了就什么也不生成 - 若用绝对定位,记得父元素设
position: relative,否则top/left会相对于视口计算
display: none 或 visibility: hidden,它的 ::before 和 ::after 也一并消失——这不是 bug,是规范行为。


















