根本原因是浏览器和系统对字体度量的解读不同:Chrome依em-box、Firefox依ascent/descent、iOS用Core Text、Android用FreeType,导致line-height计算锚点不统一,加之vertical-align和box-sizing未约束时会进一步放大偏差。

line-height 在 iOS、Android、Chrome、Firefox 之间渲染高度不一致,不是你写错了,而是浏览器和系统底层对字体度量(font metrics)的解读不同——line-height 的计算锚点本身就不统一。
Chrome 和 Firefox 的行高基准根本不同
Chrome 默认按字体的 em-box 高度推算行框(line box),而 Firefox 更依赖字体内置的 ascent 和 descent 值。这两个值在不同字体里差异很大,尤其 Web Font 加载后会立刻触发重排,造成“文字上浮/下沉”几像素的跳变。
-
line-height: 1.5在思源黑体下可能生成 24px 行高,在 Roboto 下却变成 22px - 后备字体(fallback font)缺失时,各浏览器选字逻辑不同,间接改变实际行高
- 不用单位的数值(如
1.5)虽可继承缩放,但基线参考点仍由字体决定,不是绝对可靠
iOS 和 Android 的字体引擎与排版策略差异
iOS 使用 Core Text 渲染,Android 多用 FreeType 或 Skia,两者对 ascender/descent 的采样精度、subpixel 渲染开关、甚至字号 rounding 规则都不一样。再加上 Safari 强制启用 -webkit-text-size-adjust(除非显式关掉),进一步放大偏差。
- 同一段
line-height: 20px在 iOS 上可能撑出 21px,Android 上只占 19px - iOS 对单行溢出内容会“拉高行框”容纳,Android 则倾向裁剪或换行,导致视觉高度突变
- 未设
box-sizing: border-box时,padding+border叠加会让高度偏差更难排查
表单控件(input/button)里 line-height 几乎无效
input[type="text"] 和 button 这类替换元素,line-height 不参与垂直居中计算——它们靠的是 height + padding + font-size 的组合。强行设 line-height 不仅没用,还可能在 Safari 中引发基线错位。
立即学习“前端免费学习笔记(深入)”;
- 正确做法:
height设固定值(如44px),再用padding控制文字上下留白 - 避免
line-height: 0+padding的写法,某些安卓 WebView 会忽略line-height: 0导致意外撑高 -
textarea支持line-height,但需搭配resize: none和overflow: hidden才能稳定高度
vertical-align 悄悄拖垮整行高度
vertical-align 只对 inline 或 inline-block 元素生效,但它会改变整行的基线位置,进而影响该行所有元素的 line-height 实际占用空间。一个没设 vertical-align 的 img 就能让父容器多出 2–3px 高度。
-
img、input、button默认是vertical-align: baseline,底部空隙其实是为 descender(如 “g”、“y” 下延部分)预留的 - 混排多个
inline-block元素时,只要有一个没设vertical-align: top或middle,就可能错位 - 别在已设死
line-height的容器里用vertical-align: text-bottom—— 它的语义模糊,各浏览器实现不一
真正稳定的跨平台行高控制,从来不是靠调一个 line-height 值搞定的;它需要同时约束字体加载顺序、盒模型、基线对齐、以及控件自身的渲染特性。最容易被忽略的,其实是 box-sizing: border-box 和 vertical-align 这两个看似无关的属性——它们不动声色地决定了 line-height 最终有没有机会生效。


















