1、inline-block与baseline
vertical-align属性的默认值baseline在文本之类的内联元素那里就是字符x的下边缘,对于替换元素则是替换元素的下边缘。但是,如果是inline-block元素,则规则要复杂了:一个inline-block元素,如果里面没有内联元素,或者overflow不是visible,则该元素的基线就是其margin底边缘;否则其基线就是元素里面最后一行内联元素的基线。
例子:两个同尺寸的inline-block水平元素,唯一区别就是一个是空的,一个里面有字符,代码如下
.dib-baseline {
display: inline-block;
width: 150px;
height: 150px;
border: 1px solid #cad5eb;
background-color: #f0f3f9;
}
<span class="dib-baseline"></span>
<span class="dib-baseline">x-baseline</span>
如图所示
明明尺寸、display水平都是一样的,结果两个却不在一个水平线上对齐,为什么呢?上面的规范已经说明了一切。第一个框里面没有内联元素,因此基线就是容器的margin下边缘,也就是下边框下面的位置;而第二个框里面有字符,纯正的内联元素,因此第二个框就是这些字符的基线,也就是字母x的下边缘了。于是,我们就看到了左边框框下边缘和右边框框里面字符x底边对齐的结果。
我们在来看将两个元素都设置line-height为0后的结果
因为字符实际占据的高度是由line-height决定的,当line-height变成0的时候,字符占据的高度也是0,此时,高度的起始位置就变成了字符内容区域的垂直中心位置(半行距为-1em/2),于是文字就有一半落在框的外面了。由于文字字符上移了,自然基线位置(字母x的底边缘)也往上移动了,于是两个框的垂直落差就更大了。
对于上一章说的几张图片顺序排列有间隙的问题,如果我们在最后一个占位的元素后面新增同样的x-baseline字符如下图示:
现在行高line-height是0,则字符x-baseline行间距就是-1em,也就是高度为0,由于CSS世界中的行间距是上下等分的,因此,此时字符x-baseline的对齐点(我的理解应该是高度,呼应前文,对齐点容易误导)就是当前内容区域(可以看成文字选中背景区域)的垂直中心位置。由于图5-34中的x-baseline使用的是微软雅黑字体,字形下沉明显,因此,内容区域的垂直中心位置大约在字符x的上面1/4处,而这个位置就是字符x-baseline和最后一行图片下边缘交汇的地方。由于前面的是一个inline-block的空元素,因此基线就是自身的底部,和x底部基线对齐,于是下移了差不多3/4个x的高度,这个下移的高度就是上面产生的间隙高度。
那么解决方案要么改变占位元素的基线,要么改造“幽灵空白节点”的基线位置,要么使用其他vertical-align对齐方式。
方案一:改变占位元素的基线。只要在空的元素里面随便放几个字符就可以了。例如,塞一个空格 
.box {
text-align: justify;
line-height: 0; }
<div class="box">
<img src="1.jpg" width="96">
<img src="1.jpg" width="96">
<img src="1.jpg" width="96">
<img src="1.jpg" width="96">
<i class="justify-fix"> </i>
<i class="justify-fix"> </i>
<i class="justify-fix"> </i>
</div>
这时会发现间隙没有了!为什么呢?因为此时元素的基线是里面字符的基线,此基线也正好和外面的“幽灵空白节点”的基线位置一致,没有了错位,自然就不会有间隙啦!效果如图5-36所示
改造“幽灵空白节点”的基线位置可以使用font-size,当字体足够小时,基线和中线会重合在一起。什么时候字体足够小呢?就是0。于是,如下CSS代码(line-height如果是相对font-size的属性值,line-height:0也可以省掉)
.box {
text-align: justify;
font-size: 0; }
font-size:0下的各类对齐效果都更彻底。
使用其他vertical-align对齐方式就是让占位元素vertical-align:top/bottom之类,当前,前提还是先让容器line-height:0,例如
.box {
text-align: justify;
line-height: 0;
}
.justify-fix {
vertical-align: bottom; /* top、middle都可以 */
}
(1)图标高度和当前行高都是20px。很多小图标背景合并工具都是图标宽高多大生成的CSS宽高就是多大,这其实并不利于形成可以整站通用的CSS策略,我的建议是图标原图先扩展成统一规格,比方说这里的20px×20px,然后再进行合并,可以节约大量CSS以及对每个图标对齐进行不同处理的开发成本。(2)图标标签里面永远有字符。这个可以借助:before或:after伪元素生成一个空格字符轻松搞定。
(3)图标CSS不使用overflow:hidden保证基线为里面字符的基线,但是要让里面潜在的字符不可见。
.icon {
display: inline-block;
width: 20px;
height: 20p;
background: url(sprite.png) no-repeat;
white-space: nowrap;
letter-spacing: -1em;
text-indent: -999em;
}
.icon:before {
content: '\3000'; } /* 具体图标 */
.icon-xxx {
background-position: 0 -20px;
}
2、了解vertial-align:top/bottom
顾名思义,vertial-align:top就是垂直上边缘对齐,具体定义如下:
内联元素:元素底部和当前行框盒子的顶部对齐。
table-cell元素:元素底padding边缘和表格行的顶部对齐。
用更通俗的话解释就是:如果是内联元素,则和这一行位置最高的内联元素的顶部对齐;如果display计算值是table-cell的元素,我们不妨脑补成元素,则和元素上边缘对齐。vertial-align:bottom声明与此类似,只是把“顶部”换成“底部”,把“上边缘”换成“下边缘”。需要注意的是,内联元素的上下边缘对齐的这个“边缘”是当前“行框盒子”的上下边缘,并不是块状容器的上下边缘。
已知一个
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/7d1080fa3433a260a9151844dc864756.png)
答案:不是不对齐的。因为图片所在行框盒子的最低点是“幽灵空白节点”的底部,所以最后的表现会如图5-39所示。
3、vertial-align:middle与近似垂直居中
内联元素:元素的垂直中心点和行框盒子基线往上1/2 x-height处对齐。
table-cell元素:单元格填充盒子相对于外面的表格行居中对齐。
“基线”就是字符x底边缘,而x-height就是字符x的高度。考虑到大部分字体的字符x上下是等分的,因此,从“基线往上1/2x-height处”我们就可以看出是字符x中心交叉点的位置。换句话说就是,vertial-align:middle可以让内联元素的真正意义上的垂直中心位置和字符x的交叉点对齐。
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/5e1ee6cdbcc2b48322acef5af81e296d.png)
演示页面有两条水平线,其中,图片上线显示的是图片垂直中心位置,而贯穿整个容器的线就是容器的垂直中心位置,可以看到,默认状态下,两根线就不在一个水平线上,因为图片上的那根线趋向于和字符x的中心靠近,而不是容器的垂直中心。通常的做法是设置font-size:0,整个字符x缩小成了一个看不见的点,根据line-height的半行间距上下等分规则,这个点就正好是整个容器的垂直中心位置,这样就可以实现真正意义上的垂直居中对齐了。