爱客仕-前端团队博客园

vertical-align 解析(一)

对于这个 CSS 属性很多人可能是既熟悉又陌生,好像用法简单,但又好像经常会不起效果,或者出现不想要的效果,我们今天先从简单开始聊一聊它。

先从 W3 官网 找了找这个属性的定义和解释(有些英文水平不够翻译或不准确,有兴趣的可以自行去查阅英文原文,后续也会慢慢尝试翻译的更准确并改之)。

vertical-align

值: baseline | sub | super | top | text-top | middle | bottom | text-bottom | | | inherit
默认值: baseline
应用于: inline-level and ‘table-cell’ elements
是否可继承: NO
百分比: 基于自身的 ‘line-height’

对于 table 来说,以上值有着不同的含义,这个以后另开一篇再说,这里所表述的含义只是针对于行内元素。
在以下的定义里,对于行内非替换元素,用于对齐的 box 是那个 height 等于 line-height 的 box;
对于其他元素,用于对齐的 box 是 margin box。

含义
长度 通过距离升高(正值)或降低(负值)元素。’0cm’等同于’baseline’
百分值 – % 通过距离(相对于 line-height 值的百分大小)升高(正值)或降低(负值)元素。’0%’等同于’baseline’
baseline box 的基线与父 box 的基线对齐,如果这个 box 没有基线,则对齐该 box 的 bottom margin 的底边到父 box 的 baseline。
sub 降低 box 的基线到父 box 合适的下标位置,这个值对没有 font-size 的元素无效。
super 升高 box 的基线到父 box 合适的上标位置,这个值对没有 font-size 的元素无效。
top 子树中最高的顶端与line box顶端对齐。
middle box 的中垂点与父 box 的基线加1/2 x-height 对齐。
bottom 子树中最低的底端与line box底端对齐。
text-top 把 box 的顶端对齐到父 box 的内容区域的顶端。
text-bottom 把 box 的底端对齐到父 box 的内容区域的底端。
inherit 采用父元素相关属性的相同的指定值。

baseline(基线) 是什么?(图是网上找的)

W3 官网中的基线图
博客园中找的图

  • 行高指的是文本行的基线间的距离。
  • 基线并不是汉字的下端沿,而是英文字母”x”的下端沿

通过以上两图应该可以理解什么是基线。

  1. inline-table 元素的基线是表格第一行的基线。
  2. inlne-block 元素的基线是最后一个在普通流中的 line box (行框)的基线,除非它没有在文档流中的行框,或者它的 overflow 为非 visible 值,那么它的基线就是 bottom margin 的底边。

看过这些定义以后,我们就可以知道为什么当图片和文字混排时,图片下方总是多一点留白呢,那是因为 img 标签是替换元素,它没有 baseline,所以会用它的 bottom 边跟父 box 的 baseline 对齐,这是正常的,如果不愿意看到这个留白,可以用vertical-align: bottom; 显示地把 img 的对齐方式改成底部对齐。
因为一个 line box 由多个 inline boxes 组成,而每一个 inline box(行内框)都可以有自己的 vertical-align,所以 line box 的高度会表现出被撑高的情况,这个情况有点复杂,研究了好久没有总结出啥结论,待下回再研究完再写。

另外引申一个 line-height 中数值和百分比的区别:

代码:

1
2
3
4
5
6
<div style="line-height: 150%; font-size: 50px;">
<p style="font-size: 30px">xxxxxxxxxxxxxxxx</p>
</div>
<div style="line-height: 1.5; font-size: 50px;">
<p style="font-size: 30px">xxxxxxxxxxxxxxxx</p>
</div>
  • 数值是直接继承下来并与子元素的 font-size 相乘
  • 而百分比是先计算出真正的值再继承给后代元素的

所以以上代码中,第一个 div 中的 p 元素的 line-height 是 75px,而第二个 div 中的 p 元素的 line-height 是 45px;

总之,vertical-align 这个属性必须使用在 table cell 或者 inline-level 元素中。然而这个里所说的还仅仅是一小部分,后面研究完整再续。

以下是参考文献


《深入理解CSS中的行高》
《Visual formatting model details#line-height》
《CSS Inline Layout Module Level 3#propdef-vertical-align》
《mozilla 中 vertical-align 的解释》
《我对css-vertical-align的一些理解与认识(一)》