vertical-align適用於inline-level元素,即inline,inline-block或inline-table 。css
inline元素的外邊緣是由它的line-height決定的。
紅線:元素外邊緣,即行高的頂部和底部邊緣
。html
綠線:字體的高度。web
藍線:基線。segmentfault
上圖中,左側的那個,文本的行高設置爲與字體大小相同的高度。上下兩邊綠色和紅色的線均重合爲一條線。中間的那個,行高是字體高的兩倍。右邊的那個,行高是字體高的一半。字體
inline-block元素的外邊緣就是它的margin-box的頂部和底部邊緣。
紅線:元素外邊緣,即margin-box的頂部和底部邊緣
。spa
藍線:基線。3d
上圖中從左到右能夠看到:一個inline-block元素裏面有in-flow內容(一個「C」),一個inline-block元素有in-flow內容和overflow: hidden,一個inline-block元素沒有in-flow內容(可是內容區域有高度)。code
Inline-block元素的基線取決於元素是否具備in-flow內容:orm
有in-flow內容,inline-block元素的基線是普通流中最後一個內容元素的基線(例如左邊那個)。對於最後一個元素,它的基線是根據它本身的規則肯定位置的。htm
有in-flow內容而且使用了值不是visible的overflow,基線就在margin-box的底部邊緣那個位置(例如中間那個)。所以,它與inline-block元素的底部邊緣同樣。
沒有in-flow內容,基線也是在margin-box的底部邊緣那個位置(例如右邊那個)。
例如:下圖中紫色爲基線,兩個span均是基線對齊。兩幅圖對比能夠看出,隨着第一個span元素中內容的增多,基線下移了。
<style type="text/css"> .box { display: inline-block; width: 100px; height: 50px; border: 1px solid red; } </style> <div> <span class="box">士大夫和健康</span> <span class="box"></span> </div>
<style type="text/css"> .box { display: inline-block; width: 100px; height: 50px; border: 1px solid red; } </style> <div> <span class="box">士大夫和健康士大夫和健康</span> <span class="box"></span> </div>
【注】:若是一個元素是浮動的(float:left/right),絕對定位的(position:absolute/fixed)或者是根元素(html),那麼它被稱之爲流外的元素(out-of-flow)。若是一個元素不是流外的元素,那麼它被稱之爲流內的元素(in-flow)。
content-area:在非替換元素中,指元素中每一個字符的字體大小串在一塊兒所組成的框;在替換元素中,元素的固有高度加上任何margins, borders或padding。
inline box:每一個元素的content-area加上leading。對於非替換元素,元素的inline box的高度等於line-height的值;對於替換元素,元素的inline box的高度等於該元素的固有高度加上任何margins, borders或 padding。
line box:一行就是一個line box。line box的邊界是該行內inline boxes的最高點和最低點,即line box的頂部邊緣是該行內最高inline box的頂部邊緣,底部邊緣是該行內最底inline box的底部邊緣。
文本盒能夠當作是放在line box裏面的沒有任何對齊的行內元素。文本盒的高度等於它的父元素的字體大小。
所以,文本盒只是把line box的無格式文本圍起來了。這個盒子就是下圖中用綠線標出來的那個。由於這個文本盒與基線相關聯,當基線移動時,它也移動。
line box的基線沒法定義。line box的基線被放在可以實現全部條件的地方。
綠色:line box的文本盒。
紅色:line box的頂部和底部邊緣。
藍色:基線。
灰色:文本元素的區域。
查看line box基線的方法:在行的開頭增長一個字符,就像上圖中增長的「X」。它默認地坐在基線上。line box是垂直對齊發生的區域。line box有一條基線,一個文本盒和一個頂部和底部邊緣。
當一行中僅有行內
不可替換元素,且這些元素都是相同的 font-size、line-height和vertical-align。則content-area=font-size, line-box的高=line-height。
當一行中包含行內元素
,這些元素包括可替換和不可替換,這些元素有不一樣的 font-size和 line-height。則按如下方式計算:content-area的高由每一個不可替換元素的font-size,以及替換元素的固有高度和任何padding, borders,或margins決定。leading應用於每個元素,一半放在頂部,一半放在底部。line box的頂部邊緣是該行內最高inline box的頂部邊緣,底部邊緣是該行內最底inline box的底部邊緣。
例如:
<P style="line-height: 12pt; font-size: 12pt;"> <A style="font-size: 128pt;">anchor</A> angry text <B style="vertical-align: top">bold</B> </P>
anchor的content-area是128pt,可是他的inline box是12pt。假設字體是Helvetica,那麼
descent : 128pt*219/1000=28pt ascent : 128pt*781/1000=100pt halfleading : (12pt-128pt)/2 = -58pt inline box的top:100pt-58pt=42pt inline box的bottom:58pt-28pt=30pt
因此這個inline box的top爲基線上42pt,bottom爲基線上30pt。同理可得匿名文本angry text的top是基線上10pt,基線下2pt。因此line-box的高是44pt:基線上42pt,基線下2pt。
將angry text文本去掉,會發現父元素P高度不變。
緣由:根據W3C規範:
在由inline-level元素組成的塊容器元素中,line-height肯定了該元素內部line boxes的最小高度。這個最小高度由基線上的最小高度和基線下的最小深度組成,就像每一個line box都是由寬度爲零,擁有父元素的font-size和line-height的inline box(假想元素)開始的。
個人理解是line box是在這個假想元素的基礎上往兩邊延伸。例如:
<P style="line-height: 44pt; font-size: 12pt;"> <A style="font-size: 128pt;">anchor</A> </P>
p元素中只有anchor文本,可是該文本的inline box的top爲基線上42pt,bottom爲基線上30pt。因此line box的top爲基線上42pt,而line box的bottom不是基線上的30pt,而是原先假想元素的基線下的最小深度(即上圖中藍線到最後一條紅線的距離)。
所以,即便沒有angry text文本,基線下也會有一個最小深度,因此致使P元素的高度不變。
注:
例子中計算Helvetica字體用的219和781是修改過的數據,只是爲了讓數據好看點,實際應該是接近於225和775。
leading = line-height - font-size。
其中一半leading加到文字上方,另外一半leading加到文字下方。
line-height對可替換元素的inline box沒有影響,可是當該元素的vertical-align值爲百分比時,是有影響的。
baseline:元素的基線在line box的基線頂部。
sub:元素的基線移動到line box基線如下。
<percentage>:元素的基線經過與line-height相關聯的percentage ,相對於line box的基線進行偏移。
<length>:元素的基線經過絕對長度相對於line box的基線進行偏移。
middle:元素頂部和底部二者間的中點與line box的基線加上二分之一的x-height對齊。
text-top:元素的頂部邊緣與line box的文本盒的頂部邊緣對齊。
text-bottom:元素的底部邊緣與line box的文本盒的底部邊緣對齊。
top: 元素的頂部邊緣與line box的頂部邊緣對齊。
bottom:元素的底部邊緣與line box的底部邊緣對齊。
例如:
div { font-size: 16px; line-height: 1; background-color: #eee; margin-top: 10px; } .tall-box { border: 1px solid red; width: 40px; height: 40px; display: inline-block; } .short-box { border: 1px solid black; width: 40px; height: 10px; display: inline-block; } <div> <span class="tall-box" style="vertical-align: text-top;"> </span> <span>Exg</span> <span class="short-box"></span> </div>
若將tall-box的vertical-align變成top,得下圖
從上下兩幅圖對比能夠看出,隨着vertical-align從text-top變成top,Exg往上移,致使字體高超出了父div的邊界。這是因爲line-height的高小於字體高。
若將第一個圖中的父div的line-height變爲2,使Exg的line-height值大於字體本來的高度,則得下圖。從圖中能夠看到,紅框降低了,父div的高度變高了。這是因爲紅框是text-top對齊,由此可知道基線位置在哪裏。而基線位置的肯定能夠肯定Exg和黑框的位置。而line box的頂部邊緣是該行內最高元素的頂部邊緣,這時候最高的是Exg,所以能夠看到紅框降低,父元素變高了。
<ul> <li class="box"></li> <li class="box"></li> <li class="box"></li> </ul> <style type="text/css"> .box{ display: inline-block; } </style>
能夠看到li元素底下有間隙。
間隙產生的緣由:由於列表項位於基線上,而在基線下是放文本descenders空間。
取消該間隙的方法:
設置li元素vertical-align: middle;
在li元素內添加內容。由於內容會將基線上移。