
first-line伪元素能选中哪些内容
它只作用于块级容器(比如 p、div)的第一行文本,且必须是**渲染后实际折行前的首行**。不是“第一个换行符之后”,也不是“第一个<br>之前”——它由浏览器布局引擎动态计算,受width、font-size、letter-spacing等共同影响。
常见误判点:
- span 或 inline 元素自身不支持 ::first-line
- 如果段落开头是图片或 display: inline-block 元素,且占满整行,那“第一行”可能为空或只含空白
- visibility: hidden 或 opacity: 0 的文字仍参与首行计算,但 display: none 的内容完全不参与
支持的CSS属性非常有限
::first-line 只允许使用字体、颜色、背景、行高、字母/单词间距这类**文本渲染相关属性**。不能设置 margin、padding、border、width、height,也不能触发新格式化上下文(比如设 float 或 position: absolute 会直接被忽略)。
实操建议:
- ✅ 可用:color、font-weight、font-size、line-height、background-color、text-transform
- ❌ 无效:margin-left、border-bottom、padding-top、display、transform
- ⚠️ 注意:text-indent 虽然可用,但它作用的是整段的首字缩进,不是 ::first-line 的专属控制项
和:first-child、:first-of-type容易混淆的场景
这三个选择器目标完全不同:
- ::first-line 是**伪元素**,匹配渲染后的视觉首行
- :first-child 是**伪类**,匹配父容器中第一个子节点(哪怕它是 h2 或空 div)
- :first-of-type 也是伪类,匹配父容器中同类型标签的第一个(如第一个 p)
典型错误现象:
- 写 p:first-line 没效果 → 正确写法是 p::first-line(双冒号,现代标准)
- 给 div > p:first-child::first-line 加样式,结果只有第一个 p 的首行生效 → 这没问题,但若想所有 p 都生效,不该加 :first-child
- 在 Flex 容器里对 p 用 ::first-line,发现样式丢失 → 检查是否父级 display: flex 导致 p 被强制为单行(无换行则“首行”即全文,但部分旧浏览器处理异常)
兼容性与性能要注意的实际点
主流浏览器都支持 ::first-line,但 IE8 及更早版本只认单冒号 :first-line,且不支持双冒号语法。不过现在基本不用考虑 IE8。
真正容易被忽略的是性能陷阱:
- 页面有大量长段落(比如文章页几百个 p),每个都用 ::first-line 设置 background 或 text-shadow,可能触发频繁重排重绘
- 如果段落内容动态插入(比如通过 innerHTML 或 Vue/React 渲染),::first-line 样式不会自动“重算”首行范围 —— 它依赖浏览器 layout 阶段,一般没问题,但配合 resize 或字体加载(font-display: optional)时可能出现闪动
- Safari 对 text-stroke + ::first-line 的组合偶尔有渲染延迟,可改用 text-shadow 替代








