深入理解 CSS 属性之 vertical-align

489 阅读3分钟

「这是我参与11月更文挑战的第30天,活动详情查看:2021最后一次更文挑战

This property affects the vertical positioning inside a line box of the boxes generated by an inline-level element.

  • 官方文档的翻译:vertical-align 会影响行内级元素在一个行盒中垂直方向的位置

  • 思考:一个 div 没有设置高度时,会不会有高度?

    • 没有内容,没有高度
    • 有内容,内容撑起来高度
  • 但是内容撑起来高度的本质是什么呢?

    • 内容有行高(line-height),是行高撑起了 div 的高度
  • 行高为什么可以撑起 div 的高度?

    • 因为有 line boxes 的存在,并且 line boxes 有一个特性,即包裹每行的 inline-level
    • 而其中的文字是有行高的,必须将整个行高包裹进去,才算包裹这个 inline-level(文字有行高,行盒(line box)会包裹行高,所以行盒就有高度了,而 div 中的每一行都是一个行盒,于是 div 的高度就被撑起来了。)
  • 那么,进一步思考:

    • 如果这个 div 中有图片,文字,inline-block,甚至它们设置了 margin 这些属性呢?

    image-20210117144143161.png

    image-20210117172024739.png

可见,行盒会包裹里面的所有内容。

注意,上面的情况四中内容的对齐方式是基线对齐的,因为默认情况下,所有的行内级元素都是基线对齐的。

  • 文字的基线:"x" 的底部

  • 图片的基线:图片的底部

  • inline-block 的基线:inline-block 中没有文本时,其基线是其底部;有文本时,其基线是最后一行文本的基线("x" 的底部)

由于行盒必须把里面的所有东西都包裹进去,即使只有一张图片或一个 inline-block 元素,也会按照后面存在文本的情况进行对齐,即默认基线对齐,因此图片或 inline-block 下方就会多出几像素,以保证它们和假定存在的文本是基线对齐的。

简单点说就是,行盒里的内容在默认基线对齐的基础上,行盒要包裹所有内容。

上面讲到的基线对齐,事实上就是由 vertical-align 进行设置的,vertical-align 属性的默认值就是 baseline,即基线对齐。

  • 结论:line-box 一定会想办法包裹住当前行中的所有内容

  • 但是,为什么对齐方式千奇百怪呢?

    • 你认为的千奇百怪,其实有它的内在规律
    • 答案就是 baseline 对齐
  • 我们来看官方文档 vertical-align 的默认值,没错,就是 baseline

    image-20210118065859097.png

  • 但是 baseline 都是谁呢?

    • 文本的 baseline 是字母 x 的下方
    • inline-block 默认的 baselinemargin-bottom 的底部(没有,就是盒子的底部)
    • inline-block 有文本时,baseline 是最后一行文本的 x 的下方
  • 一切都解释通了

  • 现在,对于不同的取值就非常容易理解了,常用的取值如下:

    • baseline(默认值):基线对齐(你得先明白什么是基线)
    • top:把行内级盒子的顶部跟 line box 底部对齐
    • middle:行内级盒子的中心点与父盒基线加上 x-height 一半的线对齐
    • bottom:把行内级盒子的底部跟 line box 底部对齐
    • <percentage>:把行内级盒子提升或者下降一段距离(距离相对于 line-height 计算元素高度),0% 意味着同 baseline 一样
    • <length>:把行内级盒子提升或者下降一段距离,0cm 意味着同 baseline 一样

    image-20210215220503113.png

    image-20201121072218445.png