text-indent: 2em是唯一推荐写法,因其基于font-size等比缩放,始终视觉接近两字宽;2ch因IE不支持且中文字体下常偏小,32px在系统缩放时失效,2rem易与段落字号脱节。

text-indent: 2em 是能稳定实现“首行空两格”效果的唯一推荐写法,不是经验之谈,而是由中文字体渲染特性、系统缩放适配和浏览器计算规则共同决定的刚性选择。
为什么必须用 2em,而不是 2ch 或 32px
单位选错,缩进就只是“看起来像”,一放大字体或切到高DPI屏就露馅:
-
2em表示“当前元素font-size的两倍”,16px 字号下是 32px,20px 下是 40px——视觉上始终接近两个汉字宽度 -
2ch理论上更准(1ch ≈ 字符 “0” 宽),但 IE 完全不支持,且多数中文字体里 1ch 远小于一个汉字,实测常缩进不足一格 -
32px在 Windows 125% 缩放下还是 32px,而字变大了,缩进瞬间只剩半格,阅读节奏断裂 -
2rem若项目用 JS 动态改html { font-size }(如夜间模式),缩进会与段落字号脱节,首行突兀后退
text-indent: 2em 不生效的三个真实原因
写了没反应?大概率不是 CSS 写错,而是浏览器压根没生成可缩进的“首行盒”:
-
<p></p><div class="aritcle_card flexRow"> <div class="artcardd flexRow"> <a class="aritcle_card_img" href="/xiazai/skill11244" title="Convert Markdown To HTML And PDF - Markdown和HTML、PDF互转"><img src="https://img.php.cn/upload/skill/001/246/273/6adaf20d79f23518.jpg" alt="Convert Markdown To HTML And PDF - Markdown和HTML、PDF互转" ></a> <div class="aritcle_card_info flexColumn"> <a href="/xiazai/skill11244" title="Convert Markdown To HTML And PDF - Markdown和HTML、PDF互转">Convert Markdown To HTML And PDF - Markdown和HTML、PDF互转</a> <p>实现 Markdown↔ HTML 互转,支持导出 PDF,用于用户请求的文档格式转换。</p> </div> <a href="/xiazai/skill11244" title="Convert Markdown To HTML And PDF - Markdown和HTML、PDF互转" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span> </a> </div> </div>被设成display: inline或inline-block——text-indent只对块级盒生效 - 父容器是
display: flex或display: grid,且没触发 BFC,子<p></p>的块级行为被覆盖 - 段落开头是
<img alt="如何设置HTML段落缩进使用em单位" >、<svg></svg>等内联替换元素——缩进发生在该元素左侧,视觉上等于没动 - 某处写了
p { text-indent: 0 !important }(富文本编辑器输出常见)
最快验证方式:打开开发者工具 → 查看目标 <p></p> 的 Computed 标签页 → 确认 display 是 block,且 text-indent 最终值为 2em(不是 0 或 auto)。
立即学习“前端免费学习笔记(深入)”;
表格单元格(<td>)里怎么安全缩进
<p><code>text-indent 在 <td> 中极易失效,因为:
<ul>
<li>默认 <code>display: table-cell,单行短文本时浏览器可能不生成明确的“首行盒”
text-align: center 或 right 会把缩进后的文字再拉回,看起来没动text-indent: 0 !important
更稳妥的做法:不用 text-indent,直接给 <td> 加 <code>padding-left: 2em——它不依赖行盒,兼容所有表格模式;若需保留首行缩进语义(比如导出 PDF),则包裹一层 <div style="text-indent: 2em">。
<p>真正难的不是敲下 <code>text-indent: 2em,而是确认它在目标元素上是否真的被计算为非零值——这取决于 display 类型、父容器格式化上下文、首行内容构成,三者缺一不可。


















