第三章 · 3.1 节
::before 与 ::after
这两个伪元素会在被选中元素的内容前后各"生成"一个虚拟子元素,让我们无需修改 HTML 结构,就能用纯 CSS 添加装饰性内容。它们是伪元素家族中使用频率最高的一对。
content 属性
没有 content 属性,::before / ::after 就不会被渲染——哪怕只是空字符串,也必须显式声明。
.required::after { content: " *"; color: #b3452c; }
效果预览
邮箱 *
content 除了字符串,还能引用属性值或图片:
a[href]::after { content: " (" attr(href) ")"; } .icon::before { content: url(icon.svg); }
装饰性图形
因为伪元素本质是一个可定位、可设置尺寸的盒子,配合 position 与 border,可以画出许多不需要额外图片的图形。
.card { position: relative; } .card::before { content: ""; position: absolute; top: 0; left: 0; width: 4px; height: 100%; background: #8a5a2e; }
效果预览:左侧装饰条
卡片内容
实战:纯 CSS 提示气泡
借助 ::after 生成气泡本体,再用 ::before 生成一个旋转 45° 的小三角作为箭头:
.tip { position: relative; } .tip::after { content: attr(data-tip); position: absolute; bottom: calc(100% + 8px); left: 50%; transform: translateX(-50%); background: #26233a; color: #fff; padding: 4px 10px; border-radius: 4px; font-size: 12px; white-space: nowrap; opacity: 0; pointer-events: none; transition: opacity .15s; } .tip:hover::after { opacity: 1; }
配合计数器使用
counter-reset / counter-increment 与 content: counter(name) 联手,可以实现自动编号,且能跨越多级列表:
ol { counter-reset: step; list-style: none; } ol li { counter-increment: step; } ol li::before { content: counter(step) "."; color: #8a5a2e; margin-right: 6px; }
常见误区
::before/::after对img、input等替换元素不生效,因为它们没有可插入内容的"内部"。- 生成的内容默认是
inline,需要时应显式设置display。 - 伪元素内容不会被屏幕阅读器之外的辅助技术很好地支持,重要信息不应仅依赖伪元素呈现。