inline-block 的 baseline 位置

今天又着了vertical-align的道了

场景:多个display:inline-blockdiv排在一行,他们的宽高内外边距都是相同的,唯一不同的是div里面的多行文本,有的是一行,有的是多行,然后div就会在水平方向参差不齐,如下 水平方向参差不齐

开发阶段文本都是一行的,所以没看出问题,提测之后数据出现了多行文本导致没有对齐,一个bug产生了,当时看到第一反应就是水平方向的对齐问题十有八九是vertical-align导致的,手动给div.box添加一个vertical-align:middle临时解决问题,还是要知道问题产生的根源是什么。

我们知道vertical-align影响的是元素的baseline等参考线和它父元素的baseline等参考线的对齐关系,对于文本元素我们比较好按照常用的字母x来定位参考线位置,但是对于一个里面可能含有多个子元素的inline-block元素而言,它的baseline在哪呢?

The baseline of an 'inline-block' is the baseline of its last line box in the normal flow, unless it has either no in-flow line boxes or if its 'overflow' property has a computed value other than 'visible', in which case the baseline is the bottom margin edge. --w3c

这个规则我也是在查找资料的过程中第一次知道,按照这个规则重新来看我们上面的布局,box元素里面有一个h5p元素,p元素是最后一个行元素( in-flow line boxes),那么p元素的baseline就是父元素box元素的baseline,所以三个box元素水平对齐时的参考位置就变成了它们里面的三个p元素对齐,这与图中的表现是一致的,三个p元素底部对齐(多行文本时每一行文本都有自己的baseline,按照「最后一个行元素」的规则使用最后一行元素的baseline),这导致它们的父元素box没有对齐

# 为什么添加vertical-align:middle可以让box对齐?

我是真的很烦这个属性的,相关的解释和资料看过很多次,还是觉得很烦,一句话此时:元素box的中部与父元素的基线加上父元素x-height(x高度)的一半对齐。这个时候box的自身高度参与排布规则,而不是默认的baseline,所以避免了上面的问题(改为top``bottom等也是一样的效果)。

我们还可以改变overflow属性使其不为visible,比如overflow:hidden来达到同样的效果,这个时候是因为我们破坏了上面w3c规则的限定条件 if its 'overflow' property has a computed value other than 'visible', box元素的baseline不再由p元素决定,而是由自身的底部位置来决定,这样三个box的参考位置就相同了,也就能水平对齐了

水平方向对齐

online demo👇🏻