text-indent是浏览器原生支持的首行缩进方案,仅作用于块级元素首行,推荐用2em等相对单位;内联元素无效,padding-left会整体位移段落,中文悬挂需结合ch/em单位或text-rendering优化。
用 text-indent 设置首行缩进最直接
浏览器原生支持,不用 js、不依赖结构,text-indent 就是干这事的。它只作用于块级元素(比如 p、div)的第一行,后续行不受影响。
常见错误是给 span 或 a 这类内联元素加 text-indent——没用,它压根不生效。
- 值写
2em比20px更稳妥:字体缩放时能等比缩进 - 负值(如
-1em)可用于悬挂缩进,但要小心文字被裁切 - 如果父容器设置了
text-align: justify,首行缩进依然有效,但两端对齐可能让视觉缩进变弱
为什么 padding-left 不是好选择
padding-left 看起来也能“推”出空隙,但它动的是整个盒子的左内边距,不是首行。这意味着:
- 整段文字整体左移,包括第二行、第三行……破坏段落结构语义
- 如果段落有背景色或边框,会连带把空白也染上色,视觉上很怪
- 和
text-indent同时用会叠加,容易缩进过头,调试时难定位
遇到中文标点悬挂怎么办
默认情况下,中文句号、顿号、引号等标点会“挤”在行尾,有时缩进后它们悬在行外,看着别扭。这不是 text-indent 的问题,而是排版引擎行为。
目前没有通用 CSS 属性能自动处理中文悬挂缩进,但可以:
立即学习“前端免费学习笔记(深入)”;
- 用
text-rendering: optimizeLegibility微调渲染,部分浏览器下略有改善 - 避免在缩进值里用固定像素(如
20px),改用2ch或2em,让缩进和当前字号/字宽挂钩 - 若必须精确控制,得靠 JS 测量首字符宽度再动态加
margin-left,但太重,一般项目不值得
Flex/Grid 容器里 text-indent 失效?
当 p 标签被包在 display: flex 或 display: grid 的父容器中,且父容器设了 align-items: center 或类似属性时,text-indent 有时会“看起来没反应”。
本质不是失效,而是父容器的对齐逻辑干扰了基线计算。解决方法很简单:
- 给段落本身加
align-self: flex-start(Flex 场景) - 或者换用
margin-left配合display: inline-block强制触发块格式化上下文 - 更干净的做法:缩进逻辑交给父容器的
padding-left,段落自身保持纯内容流
真正要注意的其实是缩进单位和上下文的关系——em 看的是当前元素字体大小,rem 看根字体,ch 看 “0” 字宽。同一段 CSS 在不同嵌套层级里表现可能不一样,调的时候得盯着实际渲染结果看,别光信代码里写的数字。










