伪元素必须依附于真实HTML元素才能生效,单独使用::before或::after无效;需声明content属性才渲染,且默认不参与文档流与布局计算,仅适用于装饰性内容。
单独写 ::before 或 ::after 不会渲染任何内容,它们只能作为某个已存在 HTML 元素的伪类附加部分。比如 div::before 合法,但 ::before(无宿主)无效,浏览器直接忽略。
常见错误是试图用伪元素替代结构元素来“撑开”布局,结果发现高度/宽度不响应、无法参与 Flex/Grid 排列——因为伪元素默认是 display: inline,且不占据文档流中的几何位置(除非显式设 position: absolute 或触发 BFC)。
::after 在父容器内撑高?得加 content: "" + display: block + 显式尺寸或清除浮动display: flex 并对伪元素设 flex: 0 0 auto 等,但兼容性差(Safari 旧版不支持)没有 content 声明,::before 和 ::after 什么都不会渲染,哪怕写了颜色、尺寸也没用。它的值决定内容类型:空字符串 ""、文本、URL 图片、计数器,甚至 attr() 动态取属性值。
button::before {
content: "▶ ";
font-size: 12px;
}
.icon::after {
content: url("arrow.svg");
display: inline-block;
width: 16px;
height: 16px;
}
注意:content: url() 加载失败时整个伪元素消失,不会降级显示文字;而 attr(data-label) 在属性不存在时返回空字符串,不是 undefined。
content: none 是合法值,效果等同于未声明,但可用于 CSS-in-JS 动态控制显隐content 插入 HTML 标签或执行 JS;它纯属 CSS 渲染层行为@media print { ... } 重定义用 position: absolute 把伪元素钉在角落(如气泡角标、装饰性圆点)很常见,但容易忽略它对父容器高度的影响:绝对定位后脱离文档流,父容器可能塌陷,尤其当它是唯一“撑高”元素时。
.badge-container {
position: relative;
/* 若内部只有 .badge-container::after,这里高度可能为 0 */
}
.badge-container::after {
content: "NEW";
position: absolute;
top: -6px;
right: -6px;
background: red;
color: white;
font-size: 10px;
padding: 1px 5px;
}min-height、padding,或插入一个透明占位 元素
z-index 控制(前提是宿主已建立定位上下文)em 或 rem 替代固定像素值,否则缩放时偏移量失准伪元素会自动继承宿主的 color、font-family、font-size、line-height 等文本相关属性,但不会继承 width、height、margin、background(除非显式设置)。这常导致“为什么文字变小了但背景没跟上”的困惑。
例如宿主设了 background: #333,伪元素不会自动带这个背景,必须单独写;但宿主设 font-size: 14px,伪元素里不用再声明就能按 14px 渲染文字。
inherit 关键字在伪元素里仍有效,可用于强制继承某非默认继承属性(如 border-color: inherit)getComputedStyle 中的 content 值(返回空字符串),这是 CSS 规范限制伪元素不是布局主力,而是视觉补丁。真正卡住的往往不是怎么写,而是忘了它天生不占地、不传参、不响应事件——这些边界比语法更影响最终效果。