::first-line仅对块级元素生效,且只支持有限文本属性;失效主因是父元素未触发bfc、被覆盖或作用于inline元素,其选择范围动态依赖排版环境。

为什么::first-line有时完全不生效
根本原因通常是父元素没触发「块级格式化上下文」,或者被其他样式意外覆盖。常见于inline元素(如<span></span>、<a></a>)直接套用::first-line——它只对块容器生效。
- 必须作用在
display: block、table-cell或list-item等块级元素上 -
float、position: absolute、display: inline会切断伪元素继承链 - 如果父元素有
line-height: 0或font-size: 0,第一行可能“不可见”,但样式其实已应用 - 某些CSS重置库(如Normalize.css)会默认给
p加margin,导致视觉上第一行偏移,误判为失效
::first-line能改哪些样式
它只支持有限的文本相关属性,不是所有CSS都能用。超出范围的声明会被浏览器静默丢弃,且不会报错,容易让人困惑。
- 允许:
color、font系列(font-size、font-weight等)、line-height、letter-spacing、word-spacing、text-decoration、text-transform、vertical-align - 禁止:
margin、padding、border、width、height、background(部分浏览器支持background-color,但不可靠) - 特别注意:
text-indent虽可用,但它影响的是整段首行缩进,不是“仅第一行文字”的独立控制
和line-height、换行逻辑的关系
::first-line选中的不是“前N个字符”,而是渲染后实际出现在第一行的所有文字。这意味着它高度依赖排版环境,不是静态文本切片。
- 宽度变化(如窗口缩放、字体加载延迟)可能导致原本在第二行的字被挤回第一行,样式自动应用过去
-
line-height设得过大,可能让单个短句占两行,此时::first-line只作用于第一个换行符前的部分 - 遇到
<br>或white-space: pre-wrap时,::first-line仍以视觉第一行为准,不认HTML换行标签 - 中文里全角标点、英文单词断行、
hyphens: auto都会动态改变“第一行内容”,样式边界随之浮动
替代方案:当::first-line不够用时
真要精确控制首行内某几个字(比如首字下沉+首行变色),::first-line无能为力,它无法嵌套选择或定位子节点。
- 手动包裹:
<p><span class="first-line">这是第一行</span>后面是第二行...</p>,再用类名控制 - JS辅助:用
getClientRects()计算首行文本范围,动态插入<span></span>,但要注意重排重绘开销 - 避免滥用:如果只是想突出段落开头,
text-indent+font-weight组合往往更稳定 - 警惕兼容性:
::first-line在IE中支持但有bug(如不响应font-variant),现代项目可放心用,但需测试Safari旧版本对text-decoration-color的支持
真正难的从来不是写对伪元素,而是预判它在不同字体、字号、容器宽度下的行为边界。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











