CSS Handbook · 伪元素

第三章 / 3.1 ::before 与 ::after

第三章 · 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);
}

装饰性图形

因为伪元素本质是一个可定位、可设置尺寸的盒子,配合 positionborder,可以画出许多不需要额外图片的图形。

.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-incrementcontent: 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 / ::afterimginput 等替换元素不生效,因为它们没有可插入内容的"内部"。
  • 生成的内容默认是 inline,需要时应显式设置 display
  • 伪元素内容不会被屏幕阅读器之外的辅助技术很好地支持,重要信息不应仅依赖伪元素呈现。