text-box-trim 能用了:把标题上下的空白削掉
行盒总比字高,标题上方那半行空白一直靠负 margin 硬抠。Baseline 之后 text-box-trim 一次修好,代价是接受它按字体度量裁切。
排版里有一个一直在将就的地方:行盒比字高。
字体的 ascent / descent 是给换行用的度量,不是视觉边界。所以一个 line-height: 1.2 的标题,上方总多出「行高减去字高」的一半 —— 在卡片里表现为「明明没写 padding,标题却顶不下去」。
以前靠什么补
两种办法,都不好:
- 负 margin 手调。
margin-top: -0.6em这种。换个字体、换个字号就失效。 - 按 em 估算。本质是同一个猜测,只是写得更体面。
它们共同的毛病是把「字体度量」硬编码进了样式。换字体就得重来一遍。
现在怎么写
h1, h2, h3 {
text-box-trim: trim-both;
text-box-edge: cap alphabetic;
}
trim-both 同时裁首尾;text-box-edge 指定裁到哪里 —— cap alphabetic 是「上缘切到大写字母顶端、下缘切到基线」。这两个值覆盖了绝大多数标题场景。
它裁的是字体度量,所以不同字体裁掉的量并不相同。这正是我要的:我要的是视觉对齐,不是数值对齐。
三个坑
一、它只管首尾,不管行间。 多行标题的行距仍然是 line-height 的事。两者不冲突,别指望 text-box-trim 去调行距。
二、只对块级盒有效。 行内元素没有独立的行盒边界,写了不起作用。要裁一个 <span>,先让它 display: block 或 inline-block。
三、中文字体的度量更糙。 西文字体的 cap height 是明确的;中文字体常把 ascent 定得很宽裕,裁完之后可能显得比预期更紧。中日文标题建议先小范围看一遍再全站铺。
我的取舍
只在标题和按钮上用,正文不用。
正文的第一行如果贴着容器顶,读起来反而更挤 —— 正文需要那点呼吸。而标题和按钮本来就是「一块色块」,上下留白是噪声不是节奏。
这一条和我对 text-wrap: balance 的态度是一致的:排版属性要解决的是眼睛看到的问题,不是数值表上的问题。 而 text-box-trim 恰好是少数几个真的在解决眼睛问题的属性。

评论
…