行高是文字排版里影响阅读体验最直接、也最容易被随手乱设的属性:行高太小文字挤成一团,行高太大段落松散拖沓,不同字体在同一行高下的实际观感还截然不同。导出 PDF 时行高问题还会被放大——网页上滚动浏览时轻微的行距差异不易察觉,但 PDF 是静态交付物,每一行的间距都被固定下来,成了文档质量的一部分。dompdf.js 基于真实排版引擎计算行框与行距,line-height 的四种取值方式(normal、数字、长度、百分比)与浏览器行为一致,vertical-align 对行内元素的垂直对齐控制同样可用,网页上调整好的行高效果在 PDF 中原样保留。本文深入讲解 line-height 的原理与取值差异、半行距机制、行内元素垂直对齐、中文与多语言场景的行高策略以及常见问题,帮助开发者把行高从看着差不多提升到精确可控,交付的文档行距稳定、阅读舒适。
line-height 支持 normal、数字、长度单位、百分比四种写法,行为差异很大:normal 由字体度量决定,约为字号的 1.2 倍左右,不同字体差异明显;数字(如 1.5)是相对字号的比例,子元素继承计算后的值;长度(如 24px)与百分比(如 150%)按父元素字号计算,但继承方式不同,容易产生意外,选错写法是行高失控的主因。
最常用的规范写法是无单位数字:line-height: 1.6 表示行高为字号的 1.6 倍,字号变化时行高自动缩放,且子元素继承的是比例而非固定值,行为最可预测。长度与百分比写法在继承时会把计算后的像素值传给子元素,子元素字号改变时行高不会跟随,是行高失控的常见来源,嵌套结构里尤其明显。
normal 值在不同字体间差异明显:思源黑体的 normal 与很多拉丁字体不同,混排时行高观感不一致。正式文档建议显式设置数字行高,把行距控制权从字体度量手里拿回来,中英文混排的段落也能保持统一的行距节奏,这是行高控制的第一步,也是性价比最高的一步,一行 CSS 解决大半问题。
行高决定行框(line box)的高度:行框高度等于行高值,多余空间平均分配到文字上方与下方,各占一半,称为半行距。理解半行距就能解释很多现象:行高变大时文字在行内垂直居中,行高过小时文字会被裁切或与相邻行重叠,因为行框容纳不下字体的 em 框,这些现象在 PDF 里同样会出现。
行内元素的高度不直接由 line-height 决定:行框高度由行内最高元素的度量决定,图片、大字号行内元素会把行框撑高,产生行高失效的错觉。控制方法是给行内图片设置 vertical-align 与合适的行高配合,或者把图片改成块级元素,行高控制才能真正生效,混排元素越多越要注意这一点。
行高还影响分页:行框是分页的最小单位,行框不会被拆成两半,页面底部放不下一整行时会整体移到下一页,产生底部空白。行高越大,这种空白出现的概率越高,多页文档在行高与页边距之间要留出平衡,必要时用页面断点控制分页位置,避免页面底部出现难看的空白带,版式更干净。
正文推荐 1.5-1.7 的数字行高,这是多数阅读场景的舒适区间;表格与代码块用 1.3-1.5 提高密度;封面与标题用 1.8-2 营造留白。字号越大,同样的倍数行高产生的绝对间距越大,大标题不需要与正文相同的倍数,标题行高 1.2-1.3 更紧凑,视觉重心更稳,层次更分明。
vertical-align 控制行内元素的垂直位置:middle 让图片或图标与文字中线对齐,sub/super 实现下标与上标,baseline 是默认基线对齐。注意 vertical-align 只作用于行内元素与表格单元格,块级元素上无效;文字与图片混排时,图片默认基线对齐会出现底部空隙,middle 或 bottom 是更常用的选择,观感更整齐。
固定长度行高(如 20pt)适合设计稿精确还原的场景,但继承陷阱要警惕:父元素用 20pt 时子元素继承 20pt 而非比例,子元素字号 16pt 时行高反而不够。设计稿还原用固定值、内容文档用数字值,两种场景分开处理,行高就不会出现莫名其妙的失控,模板可预测性更强。
<style>
body { font-size: 11pt; }
.tight { line-height: 1.3; }
.normal-lh { line-height: 1.6; }
.loose { line-height: 2; }
.icon-text { vertical-align: middle; }
.sup { vertical-align: super; font-size: 0.75em; }
.sub { vertical-align: sub; font-size: 0.75em; }
</style>
<p class="tight">紧凑行高适合表格与注释,信息密度高,但大字号下会显得拥挤。</p>
<p class="normal-lh">1.6 倍行高是中文正文的舒适区间,段落清晰易读,打印效果稳定。</p>
<p class="loose">宽松行高用于封面与重点段落,营造留白与仪式感,但不宜用于正文。</p>
<p><span class="icon-text">◆</span> 图标与文字用 vertical-align: middle 对齐</p>
<p>化学式 H<span class="sub">2</span>O 与上标 x<span class="sup">2</span> 的写法</p>
中文字体的行高表现与拉丁字体不同:思源黑体的默认行高与常见拉丁字体差异明显,中英混排段落若使用 normal,不同行的视觉行距会不均匀。统一设置数字行高后,中英文混排的行距节奏一致,这是中文文档排版中提升观感最立竿见影的一步,也是中英混排文档最值得投入的一行样式。
中文标点与行高也有关系:全角标点占据与汉字相同的 em 宽度,行高不足时标点与上下行文字容易视觉粘连。中文正文行高建议不低于 1.5,小字号(10pt 以下)时适当加大到 1.6-1.7,保证标点与文字的呼吸空间,打印后也依然清晰易读,纸质交付的阅读体验直接决定文档口碑。
自定义字体与行高:不同字体在同字号下的 em 框与上升下降部度量不同,行高观感自然不同。更换字体后要重新检查行高效果,而不是沿用旧值;模板设计阶段就把字体与行高一起确定下来,文档的整体版式才能稳定,不会因为换一个字体就全线崩坏,字体与行高要作为一个整体来设计。
表格是行高控制的重点:单元格内多行文本需要足够的行高才能清晰可读,行高太小会让表格显得拥挤压抑。建议表格统一 line-height: 1.4-1.5,配合单元格 padding 控制总高度;跨页表格的行高一致性尤为重要,避免不同页的表格行高观感不一,长表格的整体质感才能保持一致。
列表项的行高策略与正文一致,但要注意列表项之间的垂直间距:行高控制的是行内间距,项与项之间的间距用 margin 控制,两者职责不同,混用时页面垂直节奏才可控。多行列表项的第二行会与第一行对齐,行高不足时多行文本会重叠,检查时重点看两行以上的列表项,问题多出在这里。
按钮、标签这类单行元素的行高常被用来实现垂直居中(line-height 等于容器高度),这在 PDF 模板里同样有效;但文本较长自动换行时,这种技巧会瞬间失效,内容变成错乱的多行。固定高度容器里的文本,用 flex 的 align-items 居中更稳妥,换行也不怕,是现代模板的推荐写法。
Q: 行高设置了但 PDF 里看起来没变化?A: 检查是否被更具体的选择器或内联样式覆盖;再确认行高值本身是否合理(数字写法最可靠);最后检查影响行框高度的其他因素,如行内图片与 vertical-align,行框被撑高时 line-height 的效果会被掩盖,三步排查基本都能定位。
Q: 文字被裁切或行与行重叠?A: 行高小于字体实际高度时必然发生,把行高提到 1.3 以上并检查 overflow 设置;自定义字体度量异常时,用数字行高覆盖 normal,多数裁切问题都能解决,个别字体还需检查是否有内部行距设置,逐项排查后基本都能修复。
最佳实践小结:正文数字行高 1.5-1.7、标题 1.2-1.3、表格 1.4-1.5;中文混排统一行高;图片用 vertical-align: middle;行内间距用 line-height、元素间距用 margin,职责分离。按这套规范执行,PDF 的行距稳定专业,多页文档的分页也干净利落,验收体验明显提升。
下面的按钮用 dompdf.js 在浏览器端实时生成 PDF,无需后端:
这是由 dompdf.js 渲染的示例 PDF 内容。