::first-letter 实现首字下沉必须同时满足:float: left、父元素为块级、无前置标点或标签包裹、line-height 设为0.7–0.9(无单位)、overflow: hidden 清除浮动,否则仅放大字号无法真正下沉。

::first-letter 必须配 float: left 才能真正下沉
只写 ::first-letter { font-size: 3em; } 不会下沉,只会把首字撑大、顶开第二行文字。真正让文字“绕着走”的唯一可靠方式是加 float: left——它让首字脱离文本流,右侧内容才能自然折行环绕。
常见错误是误以为 font-size + color 就够了;其实没 float: left,::first-letter 渲染出来的还是一个内联盒,只是变大而已,不占多行空间。
- 父元素必须是块级(如
p、div),不能是display: flex或display: grid的直接子容器,否则文本流中断,伪元素静默失效 - 首字符前不能有换行、空格、HTML 注释(如
<p>\n今天</p>或<p><!-- 注释 -->今天</p>) - 首字不能被
<strong></strong>、<span></span>等标签包裹,否则浏览器找不到“纯文本首字符”
line-height 必须显式设为 0.7–0.9(无单位)
::first-letter 默认继承父段落的 line-height(比如 1.6)。放大后,这个内联盒的行框高度剧增,像一块竖砖立在开头,第二行文字只能从它“头顶”开始排——结果就是错位甚至重叠。
必须手动压低它的行高,数值太小()可能截断字形顶部,太大(<code>> 0.95)又容易顶开下一行:
- 中文推荐从
line-height: 0.75起试,思源黑体、Noto Sans CJK 下较稳 - 英文可略高,
0.8–0.85更贴合字母基线 - 绝对不要用
px或em,必须用无单位数值,避免嵌套缩放干扰
中文首字下沉最常踩的三个坑
中文没有大小写、基线不统一、标点干扰强,纯 CSS 很难兜底:
- 段落以《、【、“、”等全角标点开头时,
::first-letter会选中它而非汉字——上线前必须用真实 CMS 数据验证,不能只测“今天天气好” -
::first-letter无法跳过标点选第二个字;服务端或前端需预处理,例如用正则/^[\u3000-\u303f\uf900-\uf9fc\uff00-\uffef\u2000-\u206f\uff01-\uff5e]+/移除开头标点 - 某些字体(如思源宋体)ascender 偏高,仅调
line-height不够,需加margin-bottom: -0.2em微调;但慎用margin-top,可能触发新 BFC 导致整段偏移
父容器必须加 overflow: hidden 清除浮动
加了 float: left 后,父 <p></p> 高度会塌陷,后续段落会上移重叠——这不是 bug,是浮动的默认行为。
overflow: hidden 是最轻量、兼容性最好的清除方式,比 clear: both 少一层 DOM 干扰:
- 别用
display: flow-root:Safari 15.4 之前不支持,老安卓 WebView 也挂 - 如果父容器本身已是
flex或grid,::first-letter已失效,加清除也没用——得把段落移到布局容器外部 -
margin-right: 0.2em比空格或padding更稳定,控制首字与正文间距
复杂点不在样式本身,而在首字符的“真实性”——它必须是 DOM 文本流中第一个可渲染的汉字,且不受任何布局容器、预处理逻辑或富文本编辑器插入的零宽字符干扰。只要结构稍有偏差,::first-letter 就彻底静默。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











