行盒的概念 - line boxes
一个div没有设置高度的时候,会不会有高度?
- 没有内容,没有高度
- 有内容,内容撑起来高度
但是内容撑起来高度的本质是什么呢?
- 内容有行高(line-height),撑起来了div的高度
行高为什么可以撑起 div 的高度?
- 这是因为存在行盒 line boxes,并且 line-boxes 有一个特性,行盒一定要包裹所有的行内级内容
- 对于文字,文字是有行高的,必须将整个行高包裹进去,才算包裹这个行内级内容
行内级内容的多种情况
情况一:只有文字时(注意:红色是包裹的div,下面也都一样)
情况二:有图片,有文字时
情况三:有图片,有文字,有inline-block(比图片要大)
情况四:有图片,有文字,有inline-block(比图片要大)而且 inline-block 设置了margin-bottom
情况五:有图片、文字、inline-block(比图片要大)而且设置了margin-bottom并且有文字
CSS属性 - vertical-align
行盒一定要包裹所有的行内级的内容,而行内级内容在垂直方向上的对齐方式,则是通过 vertical-align 来设置。
默认基线对齐 baseline
vertical-align 的默认值,就是 baseline
基线 baseline
默认基线对齐导致了行内级内容对齐的千奇百怪,那行内级内容的基线分别是哪里?
- 文本的 baseline 是小写字母 x 的底部
因为文字的基线不是文字的最底部,所以图片和文字在一起的时候,图片下面会出现一条缝。
- 解决图片下边缘的间隙方法:
- 方法一: 设置成top/middle/bottom
- 方法二: 将图片设置为block元素
Inline-block 默认的 baseline 是 margin-bottom 的底部(没有,就是盒子的底部)
Inline-block 有文本时,baseline 是最后一行文本的基线
- 这个基线位置解释了行内级内容的多种情况中情况5的发生。
由此可知行内级元素对齐不要使用 vertical-align,因为基线会变,所以很容易乱。
vertical-align 的属性值
baseline
(默认值):基线对齐top
:将当前行内级盒子的顶部跟第一个行盒的顶部对齐middle
:将当前行内级盒子的中心线 与 父盒基线加上 x 字母高度一半 的线对齐- 父盒基线也就是同行的其他行级内容所构成的基线
- 字母 x 肯定刚好就在基线上,加上 x 字母高度一半,也就是 middle 是和字母 x 这个叉的交点对齐。
bottom
:把行内级盒子的底部跟line box底部对齐:把行内级盒子提升或者下降一段距离(距离相对于line-height计算\元素高度), 0%意味着同baseline一样 :把行内级盒子提升或者下降一段距离,0cm意味着同baseline一样
注意:设置对齐方式是给行内级元素自身设置 vertical-align 属性。同一行的其他行内级元素依然是保持基线对齐。vertical-align: top;
vertical-align: middle;
设置行内元素垂直居中
vertical-align: middle; 压根不存在居中的概念。一般居中指的是上下存在空隙,然后让一个小一点的元素居中,可是行盒必须刚好包裹内容,比如图片,图片撑满了行盒高度,这还怎么居中。
而且 middle 的对齐方式指的是:和字母 x 这个叉的交点对齐。
- 那只要让 x 字母这个交点在中线,middle 不就能设置居中了吗?
这可能会让人立即联想到 line-height 和父盒子高度相等,文字居中。这可以让文字居中,但是很遗憾,字母 x 的交叉点并不在中线上,因为字体存在文本下沉。字母 x 的交叉点在中线下面一点点。
所以,vertical-align: middle; 不能实现垂直居中。
带文本的行内块元素居中
假设父盒子中有文字和图片为兄弟元素。
设置 line-hight 也就是行盒高度和父盒高度相等,浏览器就会平分行距,让文字居中。而此时图片就没有不会居中,会顶贴着行盒顶部也就是父盒顶部。为此,我们为了让图片居中可能会设置 middle 让图片看起来居中了。
但是假如把图片换成包含文本的行内块元素,比如 span 包裹文字,转换成行内块元素,且文字在 span 中居中,并且文字大小和父元素中文字大小一样,那 span 就会垂直居中。
因为 vertical-align 的默认值 baseline 在发挥作用,它会让 span 包裹的文字基线对齐父元素中居中的文字,因为文字本身在 span 这个行内块中就是居中的,顺带着就让 span 也居中了。有种 a=b=c 的感觉。
注意两个前提:
- 行内块中文字要和父元素中文字大小一样,假设文字变大了,基线要保持一致,可是文字变大,导致行内块的中线往上提了,不再和父元素的中线重合。
- 文字在行内块中居中,因为文字不在行内块居中,到时候文字居中了,行内块也会不居中,两者脱钩了。