与其焦虑被 AI 取代或猜测前端是否已死, 不如看看 vertical-align 扎实你的基础!!!
vertical-align
设置 display
值为 inline
, inline-block
和 table-cell
的元素竖直对齐方式.
从 line-height: normal
究竟是多高说起
vertical-align
设置 display
值为 inline
, inline-block
和 table-cell
的元素竖直对齐方式.
line-height: normal
究竟是多高说起我们先来看一段代码, 分析一下为什么第二行的行高, 也就是 line-height
比第一行和第三行还要高?
<p class="border-dash-black max-w-12em text-40 Helvetica">
Hello, where are you from?
<span class="border-dash-orange Helvetica">xHelp</span>
<span class="border-dash-orange PingFang">xHelp</span>
<span class="border-dash-orange Times-New-Roman">xHelp</span>
I am from China.
</p>
要知道 line-height
就一定要先了解行盒子(line box
), 因为 line-height
的定义就是行盒子的高度.
以上面的 <p>
标签为例, 在英文从左到右的书写顺序下, 每一个内联标签和不在内联标签中的文字都是从左到右排列的. 由于宽度限制, 一行不能容下更多文字的情况下就会另起一行排列. 上图中一共有 3
行, 每一行其实就是一个看不见行盒子. 行盒子就是要容下这一行中所有的元素.
我们知道, line-height
这个属性的值默认是 normal
, 也就是说 <p>
的 line-height
值为 normal
, 按理说每个行盒子的高度应该是一样的才对, 但是为什么第二行的行盒子就是比第一行和第三行的高呢? 原因出在 normal
这个值究竟是多少?
实际上, CSS
规范中并没有指定 normal
的值究竟是多少, 不同的字体在设计时的 normal
值差别很大. 有人做过统计, Google Fonts
上 1000+
的字体的 line-height
的 normal
计算值从 0.9+
到 3.3+
很多专业术语
在深挖 normal
之前, 我们需要认识一些在字体设计领域的专业术语, 实际上其中大部分我们在 CSS
的世界中也常常听到.
baseline
: 小写字母x
的下边界x-height
: 小写字母x
的高度,CSS
中有一个专门表示这个高度的单位 excap height
: 大写字母的高度.cap
是Capital
的前三个字母,Capital
本身就有大写字母的意思ascender
: 一些字母从baseline
到高过x-height
并且通常高过cap height
的部分, 比如小写字母b
的竖直笔画descender
: 在baseline
下面的部分, 比如g
或者p
的下半部分.UPM(Unit Per Em)
: 首先em
是CSS
中表示一个字体大小的长度单位.UPM
的意思是在一个em
的长度内逻辑单元的个数. 为什么是逻辑单元呢?ascend
:baseline
到ascender
的高度descend
:baseline
到descender
的高度
实践出真知
有了上面的基础知识后, 我们就可以动手亲自看看 normal
的值究竟是多少了. 首先下载 fontforge 这款开源的字体设计软件, 然后下载 JetBrainsMono-Bold.ttf
这款开源字体文件.
可以看到 UPM
是 1000
. 并且 Ascend
和 Descend
分别是 1020
和 -300
. 当然截图中有两个上高和下深, 但我使用的是 macOS
, 所以选择了 HHead
上高和 HHead
下深.
如果我们在 CSS
中使用这款字体, 看看其高度是多少?
好奇 21.5
的高度是怎么计算的吗? 其实有了上面数据, 我们就可以计算在 font-size
默认 16px
大小的前提下, 字体的高度了, 公式很简单. 最后值为 21.12
最后算出来的高度就是 21.5
. 在我几周前构思这篇文章的时候计算值还是 21
. 有可能是因为我更新了浏览器, 也有可能是浏览器在渲染字体的计算方式远比我这里列出的公式复杂.
不论什么原因, 我们都知道了字体的 line-height
的 normal
值是怎么大概计算出来的了. 我们也可以回答为什么第二行比第一行和第三行还要高了, 就是因为第二行中的 PingFang
字体在设计时的 normal
行高就比 Helvetica
的行高要高. 由于行盒子要容纳一行中所有元素, 所以相应的就变高了.
行距
下面就出现了新的问题, 既然第二行的行高最高并且是由 PingFang
字体撑起来, 那么其他字体呢? Helvetica
和 Times New Roman
如何处理高出来部分呢? 于是引入了行距
的概念
如果我们用鼠标选中第二行出现蓝色背景, 你就会发现 Helvetica
和 Times New Roman
的橘色边框的区域处于蓝色背景垂直居中的位置. 达到这样效果就是把高出的部分一分为二, 上面放一份下面放一份. 这也就是行距.
行距翻译自英文 leading
, 其中 lead
的意思是铅. 在印刷时为了增加两行文字之间的距离就会在行与行之间加上铅条. 但是注意区分行距是两行文字 baseline
之间的距离, 行高是文字高度加上行距.
进入正题
vertical-align
字如其名, 就是垂直方向的对齐. 但是这个属性只对 display
为 inline
, inline-block
和 table-cell
的元素有效, 这里我们不讨论 table-cell