text-indent: 2em 不严格等于两个中文字符宽度,因其缩进值为当前 font-size 的两倍,受字体设计和字号影响;更准确的是使用 text-indent: 2ch。

text-indent 设置 2em 真的等于两个中文字符宽度吗?
不是。text-indent: 2em 缩进的是当前元素字体的 em 值,即 2 倍当前字号(font-size)的水平距离。对中文字体来说,1em 通常 ≈ 1 个汉字宽,但并非绝对——它取决于具体字体的设计(比如 "Microsoft YaHei" 和 "SimSun" 的 em 宽度表现略有差异),且受 font-size 实际值影响。如果你设了 font-size: 16px,那 2em 就是 32px;若父元素 font-size 是 14px,子元素未重设,则仍是 28px —— 这和“两个字符”没有直接绑定关系。
想真正缩进“两个中文字符”,该用什么单位?
更稳妥的方式是用 ch 单位:text-indent: 2ch。ch 表示 “0” 字符的宽度(即 font 中等宽数字的标称宽度),多数中文字体里,“0” 和汉字宽度基本一致,实测中 2ch 在绝大多数场景下比 2em 更接近视觉上的“两个汉字”。但注意:ch 在部分老旧浏览器(如 IE)不支持;Safari 9+、Chrome 27+、Firefox 1+ 支持良好。
替代方案(兼容性更强但略繁琐):
- 用
text-indent: 2em+ 显式设置font-family为已知等宽表现好的中文字体(如"PingFang SC", "Hiragino Sans GB", "Microsoft YaHei") - 避免在
text-indent上依赖继承的font-size,显式写死字号,例如:font-size: 16px; text-indent: 32px(但失去响应性)
text-indent 对哪些元素生效?常见失效原因
text-indent 只对块级容器(display: block 或 inline-block 等可生成行框的元素)的第一行生效;对 inline 元素、table-cell、flex / grid 容器内部直接子项默认无效。
常见踩坑点:
- 给
<span></span>或<a></a>这类默认inline元素设text-indent→ 不生效,需加display: inline-block或改为<p></p> - 父容器用了
display: flex,子段落被当成 flex item →text-indent仍有效(因为<p></p>自身是 block),但若子元素是<div style="display: flex"> 包裹文本,那里面文本就无首行概念 <li>用了 <code>white-space: pre或pre-wrap→ 首行缩进依然生效,但换行符和空格会被保留,可能掩盖效果 - 放弃
text-indent,改用padding-left模拟缩进(适用于整段左内边距统一) - 把首字单独抽成
::first-letter伪元素,并用margin-right控制它和后续文字间距,同时保持段落text-indent正常作用于第二行起 - 用
display: table-cell包裹首字 +vertical-align: bottom配合行高控制下沉,但语义性差,慎用
遇到首行缩进和首字下沉共存怎么办?
如果既要 text-indent: 2ch,又要首字下沉(如用 float: left + 大字号),要注意:浮动首字会脱离文档流,后续文字会绕排,此时 text-indent 作用的是“绕排后第一行”的起始位置,往往导致缩进错位或消失。
解决思路:
实际项目中,首行缩进和首字下沉属于不同层级的排版需求,强行共存容易互相干扰;优先确认设计是否真需两者叠加——多数出版级排版会选其一。











