flex容器下,不同大小的文字底部对齐,为什么应该使用 baseline 而不是 flex-end?
背景-从一个兼容性Bug说起
看一下最简单的例子:
代码语言:javascript复制<div class="container" style="display: flex;align-items: flex-end">
<div class="big-text" style="font-size: 26px">大字体</div>
<div class="small-text" style="font-size: 14px">小字体</div>
</div>
运行的效果如下:
可以看到两个字体所在矩形虽然对齐了,但是两个文字的底部并没有对齐。 分析原因发现,是因为文字周围有一圈空白的边距,这个边距在字体大小不同的情况下是不一致的,所以矩形区域虽然对齐了,但是文字底部没有对齐。而这个边距其实和 line-height
有关,所以首先来看看如何从 line-height
的角度出发解决问题。
从 line-height
的角度解决
为什么你不应该使用 line-height: 1
首先想到的就是把文字周围的边距给彻底去掉,也即设置 line-height: 1
,那么为什么说不应该使用这种方式呢?有以下几个原因:
- 在
line-height: 1
的情况下,文字如果长度不定,出现了换行,就会出现两行文字紧贴在一起的情况,如下。因为line-height
被用来去掉边距了,所以无法再调整换行后文字的行距了。
line-height: 1
和overflow: hidden
会出现字体上下部分被剪切的问题,如下。这里有点反直觉,line-height: 1
直觉上应该和字体的高度是一致的,但是在实际运行过程中发现,并不是这样的,主要和设备的字体有关,这里后面再详细探讨具体原因。
使用 line-height
的正确方法
在完全去掉周围边距这种方法不可用的情况下,只能通过把不同字体大小的透明边距宽度设置为一致就可以了。基本原理是 矩形区域高度 = (line-height) ≈ (fontSize 透明边距)。
修改代码如下:
代码语言:javascript复制<div class="container" style="display: flex;align-items: flex-end">
<div class="big-text" style="font-size: 26px;font-size: 30px">大字体</div>
<div class="small-text" style="font-size: 14px;font-size: 18px">小字体</div>
</div>
运行效果如下:
这样就把透明边距都控制为2px,让文字近似做到了底部对齐的效果。
关于 line-height
、font-size
和 矩形大小的更具体内容可以参考这篇掘金文章,非常清楚: https://juejin.cn/post/6971673576017494053
终极解决方案-align-items: baseline
可能更多人使用的是 align-items 的 flex-start
、center
、flex-end
这几个特性,很少使用 baseline
、first baseline
、last baseline
,但是在文字对齐上,后面的这三个特性更有用。
经过实测,align-items: baseline
可以完美的做到文字的底部对齐,修改代码:
<div class="container" style="display: flex;align-items: baseline">
<div class="big-text" style="font-size: 26px">大字体</div>
<div class="small-text" style="font-size: 14px;">小字体</div>
</div>
运行效果:
个人理解,前面比较经常用的一些属性值主要是用于盒子的对齐,而 baseline
相关的三个属性值,是让盒子内文字的 baseline
对齐。而 first baseline
和 last baseline
应该是在多行文本情况下有多个 baseline
的情况时,要对齐第一个 baseline
还是最后一个 baseline
,实测如下:
- first baseline
- last baseline