揭开 baseline & line-height & vertical-align 的面纱
背景 & 概念
先看一张来自维基百科的图,上面都是字体排印学的术语
来自维基百科
baseline(基线)
在字体排印学(CSS中的字体同样遵循字体排印学)中,基线指的是多数字母排列的基准线。
东亚字体(包括中文)没有基线,每个字符坐落在一个方形盒子中,既无升部也无降部。当它与具有低基线的字体混合使用时,东亚字符应当被调整,使其字符底部在低基线字体的基线和降部高度之间。
基线是存在于字体中的一条基准线,和字体有关。
x-height
在西文字体排印学中,x字高(英语:x-height或corpus size)是指字母的基本高度,精确地说,就是基线(baseline)和主线之间的距离,即小写字母x的高度。
在西文的具体字体以及排版术语中,x字高通常被称为一个ex,这和把大写字母M的宽度称为一个em的习惯类似。 (终于知道CSS中的em单位的含义了)
em
em 是字体排印学的计量单位,相当于当前指定的点数。
em最初表示的是字体中大写M的宽度及所用的尺寸。
在CSS中,单位em是字体点数或英寸数在名义上的高度。
em框
em框在字体中定义(也称为字符框(character box))。
实际字形可能比em框更高或更矮(所有例子中的“p”字母), font-size的值确定了各个em框的高度。
下面用边框模拟了em框,虚线代表了各个字符的em框
下面的文字中的“p”解释了“实际字形可能比em框更高或更矮”
内容区
在非替换元素中,内容区域是元素中各字符的 em 框串在一起构成的框,即顶线和底线所包裹的区域。
在替换元素中,内容区域是元素的固有高度再加上可能有的外边距、边框或内边距。
下面灰色的背景模拟了内容区:
line-height: 60px
行间距
行间距 = line-height - font-size 这个差值实际上要分为两半,分别应用到内容区域的顶部和底部。
行间距只应用于非替换元素
下面的灰色区域模拟了内容区域,黄色区域分别模拟半个行间距:
line-height: 80px
行内框
行内框 = line-height
这个框通过向内容区域增加行间距来描述
对于替换元素行内框刚好等于内容区的高度
下面两条红线之间描述了行内框:
line-height: 80px
行框
包含该行中出现的行内框的最高点和最低点的最小框
即:行框的上边界要位于最高行内框的上边界,而行框的底边位于最低行内框的下边界
当将“内容区”示例中的图片放大时,两条红线的距离变大了
这两条红线模拟了行框的区域,如下例所示:

为什么文本上面会留有空隙,图片下面会留有空隙,正常来说完全可以将两个空隙压缩掉?
原因在于垂直的默认对齐方式是基于基线对齐的(vertical-align: baseline;),而替换元素的基线位于元素的下边缘
示例
行内元素的边框边界由 font-size 而不是 line-height 控制。 换句话说,如果一个 <span> 的 font-size: 12px; line-height: 36px; 其内容区就是 12px 高,边框将包围该内容区域
<style>
.inner-line {
background-color: pink;
}
.inner-line span {
border: 1px dashed;
line-height: 36px;
font-size: 12px;
}
</style>
<div class="inner-line">
<span>This is text, Good moring, fdf dsf sad f sdf sd fs dfs df sdf ds f sd fsdfsdfs dfsd fs adfasd ds sfs sdf dsfas df asdf sad fas df sad f asdf sadf asdf asd f asdfas df sdf sd fasdfasdf sdf sad fs adf asdfasdfasd fasd f</span>
</div>内边距和边框不改变行高
外边距不会应用到行内非替换元素的顶端和低端,不过会作用于左右两端
<style>
.inner-line-02 {
background-color: pink;
}
.inner-line-02 span {
border: 1px dashed;
line-height: 36px;
font-size: 12px;
}
</style>
<div class="inner-line-02">
<span style="padding: 20px; margin: 16px;">This is text, Good moring,</span>
<span>fdf dsf sad f sdf sd fs dfs df sdf ds f sd fsdfsdfs dfsd fs adfasd ds sfs sdf dsfas df asdf sad fas df sad f asdf sadf asdf asd f asdfas df sdf sd fasdfasdf sdf sad fs adf asdfasdfasd fasd f</span>
</div>line-height中 1em 、100% 和 1 的不同
当 line-height 的值有单位时,继承的是父元素计算之后的值,即在父元素上计算
<div style="font-size: 10px;">
<div style="line-height: 1em;">
<span style="font-size: 20px">This is text, Good moring, fdf dsf sad f sdf sd fs dfs df sdf ds f sd fsdfsdfs dfsd fs adfasd ds sfs sdf dsfas df asdf sad fas df sad f asdf sadf asdf asd f asdfas df sdf sd fasdfasdf sdf sad fs adf asdfasdfasd fasd f</span>
</div>
</div>同上面的 1em,继承的是父元素计算之后的值,即在父元素上计算
<div style="font-size: 10px;">
<div style="line-height: 100%;">
<span style="font-size: 20px">This is text, Good moring, fdf dsf sad f sdf sd fs dfs df sdf ds f sd fsdfsdfs dfsd fs adfasd ds sfs sdf dsfas df asdf sad fas df sad f asdf sadf asdf asd f asdfas df sdf sd fasdfasdf sdf sad fs adf asdfasdfasd fasd f</span>
</div>
</div>当 line-height 的值无单位时,是继承值(缩放因子)而不是计算值,即在当前子元素上计算
<div style="font-size: 10px;">
<div style="line-height: 1;">
<span style="font-size: 20px">This is text, Good moring, fdf dsf sad f sdf sd fs dfs df sdf ds f sd fsdfsdfs dfsd fs adfasd ds sfs sdf dsfas df asdf sad fas df sad f asdf sadf asdf asd f asdfas df sdf sd fasdfasdf sdf sad fs adf asdfasdfasd fasd f</span>
</div>
</div>vertical-align
vertical-align 不影响块级元素中内容的对齐,可以影响表格单元的垂直对齐方式
baseline
当前元素的基线与父元素的基线对齐
如果该元素没有基线(例如 img、input ),则以该元素的底端与父元素的基线对齐
示例中: font-size: 60px; line-height: 1em; 两条虚线代表了行框,行框的高度大于了 60px ?
原因在于 font-size: 20px 的行内框元素也继承了 line-height 的值,行框包含了最高元素和最低元素
top/bottom
将元素行内框的顶端/底端和包含该元素的行框的顶端/底端对齐
text-top/text-bottom
将元素行内框的顶端/底端和父元素内容区的顶端/底端对齐
middle
将元素行内框的垂直中点与父元素基线上方0.5ex处对齐
这也解释了为什么middle之后的元素并不位于行框的中间
百分数
将元素上/下移一定的距离,这个距离由相对于元素的 line-height 值计算的
