在CSS中,行框的高度总是足以容纳它包含的所有行内级框,当一个行内级框 B 的高度小于包含它的行框高度时,则由 vertical-align属性 来决定B在行框中垂直对齐的位置。因此,vertical-align属性只对行内级元素有效,对块级元素无效。并且,该属性不能被子元素继承。
在垂直对齐时,行内非替换元素的行内级框是由 line-height 的高度定义的框,即在内容区的上下各添加半行距后的框;其他行内级元素的行内级框是由 margin-box 定义的框。因此,对一个行内级框来说,top 是指框的上边界,bottom 是指框的下边界,text-top 是指内容区的上边界,text-bottom 是指内容区的下边界。
由于替换元素没有 baseline,因此,就把它的 bottom 作为 baseline,即 baseline 和 bottom 的位置相同。
middle 是指框高度一半的位置,对于替换元素,就是 height 的一半的位置,而非替换元素则是基于 baseline 往上移动 0.5ex,即小写字母 x 的正中心。但是,很多浏览器往往把 ex 这个单位定义为0.5em,导致 middle 其实不一定是 x 的正中心。如图 3‑15 所示:
![行内级框 行内级框](http://www.waibo.wang/bible/css3/img/3/vertical-align1.png)
vertical-align属性可以使用长度值、百分比、或预定义关键字,来定义行内级框的垂直对齐方式。该属性的默认值是 baseline,也就是说,默认情况下,所有行内级框的基线都与父元素的基线对齐。
使用长度值和百分比时,通过让行内级框的基线相对父元素的基线,升高或降低指定的距离,来决定行内级框在行框中的位置。距离可以是正值,也可以是负值。正值使行内级框相对父元素的基线升高,负值则降低。
使用长度值时,可以使用绝对单位或相对单位,来指定升高或降低的距离,0cm 等同于 baseline。假设在一个段落中,包含一个 span 元素:
<p>xgh<span><span>xgh</p></code>
假设设置段落的字体大小为 120px,span 元素的字体大小为 40px、vertical-align 的值为 20px:
p {
font-size: 120px;
}
span {
font-size: 40px;
vertical-align: 20px;
}
由于vertical-align 的值为 20px,所以,行内框 span 的基线相对父元素的基线升高 20px。运行结果如图 3‑16 所示:
![vertical-align为长度值 vertical-align为长度值](http://www.waibo.wang/bible/css3/img/3/vertical-align2.png)
使用百分比时,升高或降低的距离是根据行内元素的 line-height 进行计算,0% 等同于 baseline。
如果把 span 元素的 line-height 设置为 1,vertical-align 设置为 50%,则得到的行高为 40px,进而得到升高的距离为 50% * 40px = 20px,也会得到相同的效果。
span {
line-height: 1;
font-size: 40px;
vertical-align: 50%;
}
使用预定义关键字时,是根据预定义的对齐准则,来决定行内级框在行框中的位置。预定义关键字有 baseline | sub | super | top | text-top | middle | bottom | text-bottom,默认值为baseline。根据W3C规范,不同取值的含义见表 3‑4:
属性值 | 含义 |
---|---|
baseline | 基线对齐。行内框的基线与父元素的基线对齐 |
sub | 下标对齐。将行内框的基线下降到父元素适合下标的位置 |
super | 上标对齐。将行内框的基线上升到父元素适合下标的位置 |
top | 顶部对齐。行内框的顶线与行框的顶线对齐。 |
text-top | 文本顶部对齐。行内框的顶线与父元素的text-top对齐 |
middle | 居中对齐。行内框的中线与父元素的中线对齐 |
bottom | 底部对齐。行内框的底线与行框的底线对齐 |
text-bottom | 文本底部对齐。行内框的底线与父元素的text-bottom对齐 |
基线对齐要求一个行内级框的基线与行框的基线对齐,而对于图像和表单输入元素和其他替换元素,由于它们本身没有基线,则将它们的底线与行框的基线对齐。这就使得浏览器总把替换元素的底线放在基线上,即便该行中没有其他文本。
上标对齐和下标对齐时,是行内元素的基线(图片和文本输入框的底线)相对于行框的基线上移或下移。而行内元素基线相对于行框的基线移动的距离,CSS规范中未明确规定,由浏览器自行决定,可能会因为浏览器的不同而不同。从上图的运行结果看,在Google Chrome浏览器下,移动的距离约为 1ex。
middle居中对齐,是行内元素的中线与行框的中线对齐。前面已经介绍,元素的中线与基线的距离为小写字母x高度(即ex)的一半,而大部分浏览器简单的认为1ex = 1em,因此会将基线以上二分之一em处(其实不一定是x的正中心),作为文本的中线。前面已经介绍,一个框的高度是由line-height决定的,如果增加行高,框的高度会增加,顶线就会上移,底线会下移。无论底线下移多少,bottom对齐,始终是元素的底线与行框的底线对齐;top对齐,始终是元素的顶线与行框的顶线对齐。增加行高时,行框的高度会增加,但内容区的高度始终保持不变,text-top对齐就是行内元素的顶线与行框文本的顶线对齐。
垂直对齐的预定义关键字看似简单,其实很难理解,处理起来也很棘手。下面通过一个简单实例,来看看每个预定义关键字的效果。假设在一个段落中,有 8 个 span 元素:
<p>xgh<span>baseline</span>…<span>top</span></p>
为段落定义 1.8 倍的行距,并让每个子元素 span 以不同的方式垂直对齐。由于子元素 span 会继承父元素的 line-height 属性,因此,把 span 元素的行距重置为1:
p {
line-height: 1.8;
font-size: 90px;
font-family: "Times New Roman";
border: 1px solid #444;
}
span {
line-height: 1;
color: #00f;
font-size: 20px;
}
span:nth-child(1) {
vertical-align: baseline;
}
…
span:nth-child(8) {
vertical-align: top;
}
在Google Chrome浏览器下的运行效果如图 3‑17 所示:
![vertical-align属性效果 vertical-align属性效果](http://www.waibo.wang/bible/css3/img/3/vertical-align3.png)
虽然W3C规范对 vertical-align属性已经定义得非常清楚,然而,现实的情况是,不同浏览器的解释却千差万别,甚至与规范相去万里。比如,在增加行高时,行框的高度会增加,text-top对齐将会是行内元素的顶线与行框文本的顶线对齐。但从运行结果看,并不是这个样子,似乎是行内元素的基线与行框文本的顶线对齐。
在所有的CSS属性中,vertical-align属性是最让人费解的一个,因为几乎在所有浏览器下的表现都各不相同,让人匪夷所思。