前面已經(jīng)討論了網(wǎng)頁(yè)設(shè)計(jì)中的水平對(duì)齊,下面來(lái)看垂直對(duì)齊。因?yàn)槲谋拘械臉?gòu)造將在第7章更詳細(xì)地討論,這里只是提供一個(gè)簡(jiǎn)單的概述。
line-height屬性是指文本行基線(xiàn)之間的距離,而不是字體的大小,它確定了將各個(gè)元素框的高度增加或減少多少,在最基本的情況下,指定line-height可以用來(lái)增加(或減少)文本行之間的垂直間隔,人們認(rèn)為這是一種了解line-height:如何工作的簡(jiǎn)單方法,但其實(shí)并不簡(jiǎn)單。line-height控制了行間距,這是文本行之間超出字體大小的額外空間。換句話(huà)說(shuō),line-height值和字體大小之差就是行間距。
在應(yīng)用到塊級(jí)元素時(shí),line-height定義了元素中文本基線(xiàn)之間的最小距離。注意,它定義的是最小距離,而不是一個(gè)絕對(duì)數(shù)值,文本基線(xiàn)拉開(kāi)的距離可能比line-height值更大,line-height并不影響替換元素的布局,不過(guò)確實(shí)可以應(yīng)用到替換元素(這個(gè)小秘密將在第7章揭開(kāi))。
文本行中的每個(gè)元素都會(huì)生成一個(gè)內(nèi)容區(qū),這由字體的大小確定。這個(gè)內(nèi)容區(qū)則會(huì)生成一個(gè)行內(nèi)框(inline box),如果不存在其他因素,這個(gè)行內(nèi)框就完全等于該元素的內(nèi)容區(qū),由line-height產(chǎn)生的行間距就是增加或減少各行內(nèi)框高度的因素之一。
要確定一個(gè)給定元素的行間距,只需將line-height的計(jì)算值減去font-size的計(jì)算值。這個(gè)值是總的行間距。而且要記住,這可能是一個(gè)負(fù)值。然后行間距再除2,將行間距的一半分別應(yīng)用到內(nèi)容區(qū)的頂部和底部。其結(jié)果就是該元素的行內(nèi)框。
舉個(gè)例子,假設(shè)font-size為14像素高(相應(yīng)地,內(nèi)容區(qū)的高度也是14像素),而且line-height計(jì)算為18像素。其差(4像素)除以2,將其一半分別應(yīng)用到內(nèi)容區(qū)的頂部和底部。這會(huì)得到一個(gè)18像素高的行內(nèi)框,在內(nèi)容區(qū)的上面和下面分別有2個(gè)額外的像素。聽(tīng)上去用這種方法描述line-height如何工作好像很繞,不過(guò)這樣描述有充分的理由。
一旦給定內(nèi)容行已經(jīng)生成了所有行內(nèi)框,接下來(lái)在行框的構(gòu)造中就會(huì)考慮這些行內(nèi)框。行框的高度恰好足以包含最高行內(nèi)框的頂端和最低行內(nèi)框的底端。
下面來(lái)考慮line-height的可取值。如果使用默認(rèn)值normal,用戶(hù)代理必須計(jì)算行間的垂直空間。不同的用戶(hù)代理計(jì)算出的值可能不同,不過(guò)通常都是字體大小的1.2倍,這使得行框要高于給定元素的font-size值。
大多數(shù)值都是簡(jiǎn)單的長(zhǎng)度度量(例如,18px或2em)。注意,即使使用一個(gè)合法的長(zhǎng)度度量,如4cm,但瀏覽器(或操作系統(tǒng))在實(shí)際度量中使用的標(biāo)準(zhǔn)可能并不正確,所以在你的顯示器上行高可能不是4厘米。更多細(xì)節(jié)參見(jiàn)第4章。
em, ex和百分?jǐn)?shù)值都相對(duì)于元素的font-size值計(jì)算。
當(dāng)一個(gè)塊級(jí)元素從另一個(gè)元素繼承l(wèi)ine-height時(shí),問(wèn)題會(huì)變得更為復(fù)雜。line- height 值從父元素繼承時(shí),要從父元素計(jì)算,而不是在子元素上計(jì)算。以下標(biāo)記的結(jié)果如圖6-9所示。但創(chuàng)作人員原來(lái)可能并不想這樣:
body {font-size: 10px;}
div {line-height: 1em;}/* computes to -10px */
p {font-size: 18px;}
<div>
<p>This paragraph-s 'font-size' is 18px, but the inherited 'line-height' value is only l0px. This may cause the lines of text to overlap each other lay a small amount .</p>
</div>
圖6-9: line-height小,font-size大,這就帶來(lái)了問(wèn)題
為什么這些行挨得這么近?因?yàn)槎温鋸钠涓冈豥iv繼承了line-height的計(jì)算值10px。如圖6-10所示,對(duì)于這種line-height太小的問(wèn)題,一種解決辦法是為每個(gè)元素設(shè)置一個(gè)顯式的line-height,但是這種方法不太實(shí)用。更好的辦法是指定一個(gè)數(shù),由它設(shè)置縮放因子:
body {font-size: 10px;}
div {line-height: 1;}
p {font-size: 18px;}
指定一個(gè)數(shù)時(shí),縮放因子將是繼承值而不是計(jì)算值。這個(gè)數(shù)會(huì)應(yīng)用到該元素及其所有子元素,所以各元素都根據(jù)其自己的font-size計(jì)算line-height (見(jiàn)圖6-10所示):
div {line-height: 1.5;}
p {font-size: 18px;}
<div>
<p>This paragraph's 'font-size' is 18px, and since the 'line-height' set for the parent div is 1.5, the 'line-height' for this paragraph is 27px (18 * 1.5).</p>
</div>
盡管看上去line-height在每個(gè)文本行的上面和下面平均分配了額外空間,實(shí)際上,它是在行內(nèi)元素的內(nèi)容區(qū)頂部和底部增加(或減少)一定的量來(lái)創(chuàng)建一個(gè)行內(nèi)框。假設(shè)一個(gè)段落的默認(rèn)font-size是12pt,考慮以下規(guī)則:
p (line-height: 16pt;)
由于12點(diǎn)文本的“固有”行高是12點(diǎn),前面的規(guī)則將在段落中各行文本外圍增加額外的4點(diǎn)空間。這個(gè)額外的量平均分為兩部分,一半放在各行的上面,另一半放在各行的下面?,F(xiàn)在基線(xiàn)間則有16點(diǎn)空間,這是分配額外空間的間接結(jié)果。
如果指定值inherit,元素則會(huì)使用其父元素的計(jì)算值。這與值自然繼承沒(méi)有什么不同,不過(guò)特殊性和層疊解決方案不同。這些內(nèi)容在第3章曾做過(guò)詳細(xì)討論。
既然已經(jīng)基本了解了如何構(gòu)造文本行,下面來(lái)討論相對(duì)于行框垂直對(duì)齊元素。
如果你曾用過(guò)元素sup和sub(上標(biāo)和下標(biāo)元素),或者曾用過(guò)有<img src="foo.gif" align="middle">之類(lèi)標(biāo)記的圖像,說(shuō)明你已經(jīng)做過(guò)一些基本的垂直對(duì)齊,在CSS中,vertical-align屬性只應(yīng)用于行內(nèi)元素和替換元素,如圖像和表單輸入元素。vertical-align屬性不能繼承。
vertical-align只接受8個(gè)關(guān)鍵字、一個(gè)百分?jǐn)?shù)值或一個(gè)長(zhǎng)度值。這些關(guān)鍵字有些我們很熟悉,有些可能不熟悉,包括:baseline(默認(rèn)值)、sub、super、bottom、text- bottom、middle、top和text-top。我們將分析各關(guān)鍵字如何作用于行內(nèi)元素。
vertical-align
值:
baseline | sub | super | top | text-top | middle | bottom | text-bottom | <percentage> | <length> | inherit
初始值:
baseline
應(yīng)用于:
行內(nèi)元素和表單元格
繼承性:
無(wú)
百分?jǐn)?shù):
相對(duì)于元素的line-height值
計(jì)算值:
對(duì)于百分?jǐn)?shù)和長(zhǎng)度值,為絕對(duì)長(zhǎng)度;否則,根據(jù)指定確定
說(shuō)明:
網(wǎng)頁(yè)設(shè)計(jì)中應(yīng)用到表單元格時(shí),只能識(shí)別baseline、top、middle和bottom等值
警告:要記住:vertical-align不影響塊級(jí)元素中內(nèi)容的對(duì)齊。不過(guò),可以用它來(lái)影響表單元格中元素的垂直對(duì)齊。詳細(xì)內(nèi)容參見(jiàn)第11章。
vertical-align: baseline要求一個(gè)元素的基線(xiàn)與其父元素的基線(xiàn)對(duì)齊。大多數(shù)情況下,瀏覽器都會(huì)這么做,因?yàn)?a href="/" target="_self" title="昆明網(wǎng)頁(yè)設(shè)計(jì)" style="white-space: normal;">網(wǎng)頁(yè)設(shè)計(jì)中你顯然希望一行中所有文本元素的底端都對(duì)齊。
如果一個(gè)垂直對(duì)齊元素沒(méi)有基線(xiàn)——也就是說(shuō),如果這是一個(gè)圖像或表單輸入元素,或者是其他替換元素——那么該元素的底端與其父元素的基線(xiàn)對(duì)齊,如圖6-11所示:
img {vertical-align: baseline;}
<p>The image found in this paragraph <img src="dot.gif" alt="A dot"/> has its bottom edge aligned with the baseline of the text in the paragraph.</p>
這個(gè)對(duì)齊規(guī)則很重要,因?yàn)樗?a href="http://www.margaycoffee.com" target="_self" title="昆明網(wǎng)站建設(shè)">網(wǎng)站建設(shè)上總把替換元素的底邊放在基線(xiàn)上,即使讀行中沒(méi)有其他文本。例如,假設(shè)一個(gè)表單元格中只有一個(gè)圖像。這個(gè)圖像可能實(shí)際在基線(xiàn)上,不過(guò)在某些瀏覽器中,基線(xiàn)下面的空間會(huì)導(dǎo)致圖像下出現(xiàn)一段空白。另外一些瀏覽器則會(huì)把圖像“緊包”在表單元格中,所以不會(huì)出現(xiàn)空白。根據(jù)CSS工作組的意見(jiàn),這種加空白的行為是正確的,不過(guò)大多數(shù)創(chuàng)作人員都不喜歡這種做法。
注意:對(duì)于這種加空白的行為以及相應(yīng)的解決辦法,更詳細(xì)的解釋見(jiàn)我的文章《Images, Tables, and Mysterious Gaps》(http://developer.mozilla.org/en/docs/Images._Tables._and_Myslerious_Gaps)。第7章也會(huì)更詳細(xì)地介紹行內(nèi)布局的這個(gè)方面。
vertical-align: sub聲明會(huì)使一個(gè)元素變成下標(biāo),這意味著其基線(xiàn)(或者如果這是一個(gè)替換元素,則是其底端)相對(duì)于其父元素的基線(xiàn)降低。規(guī)范并沒(méi)有定義元素降低的距離,所以對(duì)于不同的用戶(hù)代理,這個(gè)距離可能有所不同。
super剛好與sub相反,它將元素的基線(xiàn)(或替換元素的底端)相對(duì)于父元素的基線(xiàn)升高。同樣地,文本升高的距離取決于具體的用戶(hù)代理。
注意,值sub和super不會(huì)改變?cè)氐淖煮w大小,所以下標(biāo)或上標(biāo)文本不會(huì)變?。ɑ蜃兇螅?。相反,下標(biāo)或上標(biāo)元素中的所有文本默認(rèn)地都應(yīng)當(dāng)與父元素中的文本大小相同,如圖6-12所示:
span.raise {vertical-align: super;}
span.lower {vertical-align: sub;}
<p>This paragraph contains <span class="raise">superscripted</span>
and <span class="lower">subscripted</span> text.</p>
圖6-12:上標(biāo)和下標(biāo)對(duì)齊
注意:如果想讓上標(biāo)或下標(biāo)文本小于其父元素的文本,可以使用屬性font-size,這在第5章曾做過(guò)介紹。
vertical-align: bottom將元素行內(nèi)框的底端與行框的底端對(duì)齊。例如,以下標(biāo)記的結(jié)果如圖6-13所示:
.feeder {vertical-align: bottom;}
<p>This paragraph, as you can see quite clearly, contains a <img src="tall.gif" alt="tall" class="feeder" /> image and a <img src="short.gif" alt="short" class="feeder"/> image, and then some text that is not tall.</p>
圖6-13中,段落的第二行包含兩個(gè)行內(nèi)元素,其底邊彼此對(duì)齊。它們都在文本基線(xiàn)之下。
vertical-align: text-bottom是指行內(nèi)文本的底端。替換元素或任何其他類(lèi)型的非文本元素會(huì)忽略這個(gè)值。對(duì)于這些元素,將考慮一個(gè)“默認(rèn)”的文本框。這個(gè)默認(rèn)框由父元素的font-size得到。要對(duì)齊的元素的行內(nèi)框底端再與這個(gè)默認(rèn)文本框的底端對(duì)齊。因此,給定以下標(biāo)記,可以得到如圖6-14所示的結(jié)果:
img.tbot {vertical-align: text-bottom;}
<p>Here: a <img src="tall.gif" style="vertical-align: middle;" alt="tall"/> image, and then a <lmg src="short.gif" class="tbot" alt="short"/> image.</p>
vertical-align:top的效果與bottom剛好相反,類(lèi)似地,vertical-align:text-top則與text-bottom的作用相反。圖6-15顯示了以下標(biāo)記的結(jié)果:
.up {vertical-align: top;}
.textup {vertical-align: text-top;}
<p>Here: a <img src="tall.gif" alt="tall image"> tall image, and then <span class="up">some text</span> that's been vertically aligned.</p><p>Here: a <img src="tall.gif" class="textup" alt="tall"> image that's been vertically aligned, and then a <img src="short.gif" class="textup" alt="short"/> image that's similarly aligned.</p>
當(dāng)然,對(duì)齊的具體位置取決于行內(nèi)有哪些元素,它們有多高,以及父元素字體的大小。
還有一個(gè)值middle,它往往(但并不總是)應(yīng)用于圖像。你可能會(huì)從它的名字想象其效果,但你的想象與其實(shí)際效果并不完全一樣。middle會(huì)把行內(nèi)元素框的中點(diǎn)與父元素基線(xiàn)上方0.5ex處的一個(gè)點(diǎn)對(duì)齊,這里的1ex相對(duì)于父元素的font-size定義。圖 6-16更詳細(xì)地說(shuō)明了這一點(diǎn)。
因?yàn)榇蠖鄶?shù)用戶(hù)代理都把1ex處理為0.5em, middle往往將元素的垂直中點(diǎn)與父元素基線(xiàn)上方0.25em處的一個(gè)點(diǎn)對(duì)齊。不過(guò),不要指望總會(huì)這樣,因?yàn)橛行┯脩?hù)代理確實(shí)會(huì)為各元素計(jì)算準(zhǔn)確的x-height(關(guān)于x-height的更多詳細(xì)內(nèi)容見(jiàn)第5章)。
使用百分?jǐn)?shù)不能模仿圖像的align="middle"對(duì)齊。相反,如果為vertical-align設(shè)置一個(gè)百分?jǐn)?shù),會(huì)把元素的基線(xiàn)(或替換元素的底邊)相對(duì)于父元素的基線(xiàn)升高或降低指定的量(你指定的百分?jǐn)?shù)要計(jì)算為該元素line-height的百分?jǐn)?shù),而不是相對(duì)于其父元素的line-height)。正百分?jǐn)?shù)值會(huì)使元素升高,負(fù)值則會(huì)使其降低。取決于文本的升高或降低,可能看上去它放在了相鄰的行上。
下面更詳細(xì)地考慮百分?jǐn)?shù)值。假設(shè)有以下標(biāo)記:
<div style="font-size: 14px; line-height: 18px;">
I felt that, if nothing else, I deserved a
<span styles="vertical-align: 50%;">raise</span> for my efforts.
</div>
設(shè)置為50%的span元素對(duì)齊時(shí),會(huì)使其基線(xiàn)升高9像素,這是元素繼承的line-height 值(18px)的一半,而不是7像素。
最后,來(lái)考慮根據(jù)指定長(zhǎng)度垂直對(duì)齊。vertical-align很明確:它把一個(gè)元素升高或降低指定的距離。因此,vertical-align: 5px;會(huì)把一個(gè)元素與對(duì)齊前相比上升5像素。負(fù)長(zhǎng)度值會(huì)使元素下降。這種簡(jiǎn)單的對(duì)齊形式在CSS1中不存在,但在CSS2中已經(jīng)增加。
要認(rèn)識(shí)到垂直對(duì)齊的文本并不會(huì)成為另一行的一部分,它也不會(huì)覆蓋其他行中的文本,這很重要??紤]圖6-18,其中在段落中間出現(xiàn)一些垂直對(duì)齊文本。
可以看到,所有垂直對(duì)齊的元素都會(huì)影響網(wǎng)頁(yè)設(shè)計(jì)中的行高。應(yīng)該記得行框的描述,其高度要足以包含最高行內(nèi)框的頂端和最低行內(nèi)框的底端。這包括因垂直對(duì)齊上升或下降的行內(nèi)框。