::first-line和::first-letter有严格生效条件与样式限制:前者需存在行盒且仅支持文本相关属性,后者对中文无效;共存时后者嵌套于前者内,受层叠规则影响。

::first-line 和 ::first-letter 不是万能装饰工具,它们各自有严格生效条件和属性限制,混用时还存在固定层叠顺序——直接套用常失效,关键在理解“谁管哪一段、能动哪些样式”。
为什么写了 ::first-line 却完全没反应
不是选择器写错了,而是浏览器压根没生成可挂载的行盒(line box)。常见静默失效场景:
- 父容器用了
display: flex或display: grid—— 伪元素被忽略,不报错也不渲染 - 目标元素是
span、a等默认display: inline的标签,即使加了display: block,部分浏览器仍不触发行盒生成 - 段落开头有
\u200B(零宽空格)、\u3000(中文全角空格)或<img>—— 行盒起始点被干扰,首行可能为空 -
font-size: 0或line-height: 0—— 首行被压缩到不可见,伪元素无内容可作用
::first-line 能设哪些样式、哪些绝对不行
它只接受影响「文本渲染结果」的属性,超出范围的声明会被浏览器静默丢弃(不报错,也不生效):
- ✅ 安全可用:
color、font-size、font-weight、text-transform、letter-spacing、line-height、background-color - ⚠️ 有条件支持:
text-indent虽能生效,但它作用于整段,不是首行专属;background-image在 Safari 和旧版 Firefox 中常被忽略 - ❌ 完全无效:
margin、padding、border、width、height、display(设成inline-block会直接让伪元素失效)
特别注意:letter-spacing 实际支持,但中英文混排时断点易偏移;想靠它“松散首行”,不如组合 font-size: 1.1em + line-height: 1.3 更可控。
::first-letter 对中文无效,别白费劲
::first-letter 只识别 Unicode 字母类字符(Lu/Ll/Lt),汉字属于 Lo 类,在 Blink/WebKit 引擎中不被识别为“首字母”。给中文段落写 p::first-letter { text-transform: uppercase } 一定没反应。
- 英文段落开头是
A、é、"Hello"中的"+H,才可能生效 - 数字(如
1)也能被选中,但text-transform对它无视觉变化 - 服务端注入
<span class="first-char">你</span>,再用 CSS 控制,是最稳定方案 - CSS
initial-letter(Chrome 117+、Safari 16.4+)可实现首字下沉,但对中文大小写无影响
两者共存时的渲染逻辑和坑
::first-letter 始终嵌套在 ::first-line 内部,不是并列关系。例如:
p::first-line { color: #666; }
p::first-letter { font-size: 2em; color: #d44; }
效果是:首行文字整体灰,但其中第一个字母变大且红——后者样式叠加在前者之上。
- 如果
::first-line设了background-color,而::first-letter没设透明背景,首字母会被盖住一部分 - 不要指望用
::first-line控制缩进:text-indent是正解;margin-left在伪元素里写了也白写 - 响应式下窗口缩放、字体加载、
word-break变化都会导致首行/首字覆盖范围实时重算——这不是 bug,是设计行为
最易被忽略的一点:当段落里嵌了 <img> 或 <svg></svg>,且它们恰好出现在首行末尾,::first-line 只作用于纯文本部分,不会影响这些内联元素的样式。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











