::first-letter要实现首字下沉,必须同时满足结构干净、父容器合规、样式配齐三条件;否则浏览器静默跳过而非报错。

只写 ::first-letter { font-size: 3em; } 不会下沉,只会把首字撑高、顶开第二行;真正“沉下去”必须同时满足结构干净、父容器合规、样式配齐三个条件。
为什么 ::first-letter 写了却完全没反应
浏览器不是报错,而是静默跳过——它对 DOM 结构极其苛刻:
- 父元素用了
display: flex或display: grid:文本流被切断,伪元素直接失效 - HTML 中首字符前有换行、空格、
<!-- 注释 -->或零宽字符(比如富文本编辑器插入的) - 首字被
<strong>、<span>等内联标签包裹,例如<p><strong>今</strong>天…</p> - 段落以《、【、“、”等全角标点开头,
::first-letter选中的是标点而非汉字,结果引号被放大三倍溢出
::first-letter 必须配齐的三个核心样式
缺一不可,单改一个大概率导致文字错位或首字“立着不沉”:
-
float: left:唯一能触发文字环绕的属性;不加它,后续文字从首字右侧平齐开始,不是下沉 -
line-height: 0.75(无单位):必须显式设置;继承父级line-height: 1.6会让放大后的首字像竖砖立着,文字只能从它“头顶”绕 -
font-size: clamp(2rem, 4vw, 3.5rem):中文建议响应式写法;固定值至少2.5em,2em在多数字体下视觉无下沉感
父容器必须加 overflow: hidden 清除浮动
不处理浮动,段落高度会塌陷,后续段落会上移重叠:
立即学习“前端免费学习笔记(深入)”;
-
overflow: hidden是最轻量、兼容性最好的清除方式(IE6+ 都支持) - 别用
clear: both——需要额外 DOM 节点,破坏语义 - 慎用
display: flow-root——Safari 15.4 之前不支持 - 如果父容器本身是
flex或grid,加清除也没用,::first-letter已提前失效,得把<p>移出该容器
中文场景下最容易被忽略的硬伤
不是样式没写够,而是底层渲染逻辑不同:
-
::first-letter无法跳过开头标点选第二个字——CMS 或前端需用正则/^[\u3000-\u303f\uf900-\uf9fc\uff00-\uffef\u2000-\u206f\uff01-\uff5e]+/预处理 - 思源宋体等字体 ascender 偏高,仅调
line-height不够,可加margin-bottom: -0.2em微调,但margin-top易触发新 BFC 导致整段偏移 - 手写体、细黑体等字体放大后字形发虚或撑破行框,优先指定
font-family: "PingFang SC", "Noto Sans CJK SC" - 移动端 viewport 缩放后,iOS Safari 偶有重绘异常;可在
@media中关闭float,改用display: inline-block+vertical-align: top
真正麻烦的从来不是写几行 CSS,而是确认 DOM 结构干净、字体加载完成、且没被其他规则意外覆盖——这些地方不检查,::first-letter 就永远静默失效。


















