測(cè)試代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vertical與line-height測(cè)試</title>
<style>
* {
margin: 0;
padding: 0;
}
div {
border: 1px solid #000;
width:300px;
height: 200px;
line-height: 200px;
text-align: center;
}
p {
display: inline-block;
vertical-align: middle;
img {
vertical-align: middle;
border: 1px solid #000;
}
</style>
</head>
<body>
<div>
<p class="p">我啊</p>
<img src="http://mat1.gtimg.com/www/qq2018/imgs/qq_logo_2018x2.png" alt="圖片加載失敗">
</div>
</body>
</html>
一、line-height的性質(zhì)
???????line-height在CSS中的定義為行高,具體計(jì)算方法如圖所示:

???????由圖中可以看出,在不設(shè)置元素高度以及padding、border、margin均為0的情況下,元素本身的高度就是它的line-height值,而文本與文本之間的間隙就是(line-height - font-size)。所以此時(shí)通過(guò)設(shè)置line-height值,就等于在設(shè)置元素高度(元素高度不固定且padding、border、margin不為0時(shí),高度由padding、border、margin及行高共同控制)。
???????那么,在了解了line-height對(duì)元素高度的控制原理之后,就不難理解文本元素垂直居中的原理,令height=line-height,或者不設(shè)置height(默認(rèn)line-height),都是通過(guò)讓height = (line-height - font-size)/2 + font-size + (line-height - font-size)/2,然后文本居中顯示。如果在一個(gè)<div>中嵌套一個(gè)<p>分別把p元素display: inline-block、display:line,則為下圖展示的原理:
-
display:block(默認(rèn));
p元素與div元素等高且等寬 -
display:inline-block;
p元素與div元素等高,與內(nèi)容等寬 -
display::inline;
p元素與內(nèi)容等高且等寬
???????上面三張圖片,分別展示了p在三種元素類型下的不同表現(xiàn)形式,從中可以理解inline-block的工作機(jī)理(子元素繼承),實(shí)際上是通過(guò)控制高度,使內(nèi)容(inline)居中,而不是元素本身居中。那么試想一下,如果在p元素前插入一段純文本,或者P元素是多行文本,那么div中顯示情況又會(huì)如何?圖中的div的height是固定的100px,那如果不設(shè)置height的值,又會(huì)如何顯示??請(qǐng)各位自己動(dòng)手進(jìn)行驗(yàn)證~
???????另外,從第一張及第二張圖中還可以看出一個(gè)小問(wèn)題,p元素的邊框溢出了div的盒子。通過(guò)父元素div設(shè)置固定值height與不設(shè)置固定值時(shí),確定子元素p的height與父元素div的height的計(jì)算關(guān)系。希望各位同仁能夠找到自己的答案~
二、vertical-align的性質(zhì)
???????vertical-align從字面上理解就是垂直排列,這貨有一大堆屬性可寫。不要覺(jué)得這貨平常不怎么用,實(shí)際上它無(wú)處不在。因?yàn)闉g覽器默認(rèn)設(shè)置中,inline與inline-block的對(duì)齊方式,就是baseline基線對(duì)齊,想要理解各種屬性的對(duì)齊方式,我們先看一下各種屬性的意義,如圖所示:

???????這個(gè)圖實(shí)在是難畫,從水印也可以看出來(lái),我是直接從網(wǎng)上粘過(guò)來(lái)的,如有雷同,我選擇刪除(哈哈,skr)
vertical-align各種屬性:
vertical-align: baseline;
vertical-align: sub;
vertical-align: super;
vertical-align: text-top;
vertical-align: text-bottom;
vertical-align: middle;
vertical-align: top;
vertical-align: bottom;vertical-align對(duì)齊方式:
1)瀏覽器默認(rèn)baseline對(duì)齊;
2)設(shè)置了middle/baseline的情況下,元素自身middle/baseline會(huì)和行內(nèi)其他元素的baseline對(duì)齊(一個(gè)inline-block元素,如果里面沒(méi)有inline內(nèi)聯(lián)元素,或者overflow不是visible,則該元素的基線就是其margin底邊緣,否則,其基線就是元素里面最后一行內(nèi)聯(lián)元素的基線——摘自張?chǎng)涡瘛禖SS深入理解vertical-align和line-height的基友關(guān)系》);
3)設(shè)置了top/bottm情況下,自己的top/bottom會(huì)和行內(nèi)其余元素中最高的top/最低的bottom對(duì)齊;其余補(bǔ)充:
1)verti-align只可用于inline或inline-block;
2)vertical-align必須在目標(biāo)元素中聲明,對(duì)其他元素不產(chǎn)生影響;
3)vertical-align如果設(shè)置%屬性的話,以line-height值為計(jì)算基數(shù);
4)vertical-align默認(rèn)屬性為baseline;
三、line-height與vertical-align的搭配使用,元素垂直居中
???????在第一部分最后我說(shuō)到了,通過(guò)line-height達(dá)到的居中效果,實(shí)際上是子元素繼承了父元素的height與line-height設(shè)置,本質(zhì)上是內(nèi)容的居中,而非元素本身的居中。試想一下,如果div中嵌入的是img而非p元素,如何在一個(gè)height設(shè)置了固定值的div中,將img垂直居中顯示??(這里的固定值,包括從父元素按%計(jì)算而來(lái)的固定值。未設(shè)置固定高度值的,高度以內(nèi)容為準(zhǔn),可通過(guò)padding-top/bottom或line-height設(shè)置居中)
???????這就涉及到了line-height與vertical-align的配合使用。
在實(shí)際操作前,首先回憶一下剛才的內(nèi)容:
- line-height通過(guò)控制元素高度與其內(nèi)容字體高度的差值均分,實(shí)現(xiàn)垂直居中;
- vertical-align默認(rèn)baseline對(duì)齊;
- vertical-align在目標(biāo)元素中聲明,且目標(biāo)元素一定是inline或inline-block屬性的元素;
Duang~準(zhǔn)備就緒?,F(xiàn)在開始說(shuō)明操作過(guò)程,同樣以圖片直觀的展現(xiàn):
-
當(dāng)給div一個(gè)固定的height值,在不設(shè)置line-height及vertical-align時(shí),由于設(shè)置了* {margin: 0;padding: 0;},圖片是緊貼頂端的。
-
讓我們來(lái)加一段文字,讓理解更直觀。此時(shí),我們就能看到vertical-align的默認(rèn)屬性baseline對(duì)齊。圖片由于不是文字,它的基線就是它的margin底(此圖中margin為0),即border-bottom。
-
下面讓我們給img屬性增加vertical-align: middle;,可以看出文本與圖片似乎居中對(duì)齊了,但是文本呢,有一點(diǎn)emmmmmm,不那么居中!因?yàn)?strong>圖片是以自身的middle line與文本的baseline對(duì)齊的。所以實(shí)際的中點(diǎn)要在對(duì)齊線的上方(詳情上翻至vertical-align的對(duì)齊方式)。
-
設(shè)置div的line-height = height值,去除文字的border(防止子元素p繼承父元素div的高度后,增加border溢出)。此時(shí)文本垂直居中顯示,按照上一步的解釋,不難看出,圖片因?yàn)榕c文本并不是真正的居中對(duì)齊,所以實(shí)際上它在div中并沒(méi)有真正的垂直居中。
-
解決方案
1)那么怎么才能讓圖片真正的垂直居中呢?腦子轉(zhuǎn)的快的朋友肯定已經(jīng)想到了,可以把p元素也聲明vertical-align: middle;啊。這確實(shí)是個(gè)好方法,但是!如果文本設(shè)置了vertical-align后,它自身也并不是垂直居中了的話,那這種方法就不成立了。而且很不幸的是,情況就是這樣(控制臺(tái)可查看p元素高度,已經(jīng)溢出div盒子)。那么為什么會(huì)出現(xiàn)這種情況呢。那就要我們回想一下,如果行內(nèi)只有一個(gè)p元素或者一個(gè)img元素的話,它又是跟誰(shuí)對(duì)齊的?
???????要理解行內(nèi)元素對(duì)齊,這里就必須提出一個(gè)假設(shè),假設(shè)block元素內(nèi),存在一個(gè)empty元素。在block元素內(nèi)只嵌套了一個(gè)inline或inline-block元素時(shí),作為規(guī)則的參照物。而且empty元素雖然看不見(jiàn),但要假設(shè)它里邊有一個(gè)繼承自父元素font-size的文本,這樣它才具有正常的baseline、middle line及top、bottom等。理解了這一假設(shè),就不難理解為什么p元素設(shè)置vertical-align: middle;后,圖片仍然不是垂直居中。因?yàn)?strong>p元素中線與empty元素的基線對(duì)齊了。
???????那么有的朋友又會(huì)提出問(wèn)題了,既然圖片與文本的基線對(duì)齊,文本下移了,圖片為什么沒(méi)有跟著文本的基線一起下移呢?那是因?yàn)?strong>基線始終都只有一條,那就是empty元素的基線。這也就解釋了,為什么p元素設(shè)置了vertical-align: middle;后,只有p元素下移,而img元素紋絲不動(dòng)。因?yàn)?strong>p元素與empty元素由baseline對(duì)齊baseline變?yōu)榱薽iddle line對(duì)齊baseline,造成了下移,而img元素始終都與empty元素對(duì)齊,所以紋絲不動(dòng)。
2)俗話說(shuō)柳暗花明又一村,一條路走不通,必然有另一條路。既然改變p元素的vertical-align行不通,那就嘗試其他方法,比如改變基線的位置。
???????這就需要另一個(gè)屬性font-size,既然基線由行內(nèi)empty元素的字體大小決定,那如果我把font-size設(shè)置成0,那不是所有線全都匯聚成了一條,那么文字的居中顯示,不就變成了這條匯聚線的居中顯示?這樣的話,跟基線對(duì)齊豈不是就成了居中對(duì)齊?簡(jiǎn)直美滋滋~
???????這樣又有朋友說(shuō)了,這樣文字就消失不見(jiàn)了,一個(gè)問(wèn)題解決了,又出來(lái)個(gè)新問(wèn)題,這什么時(shí)候是個(gè)頭?????別急,這個(gè)方法簡(jiǎn)單,那就是給p元素,單獨(dú)加一個(gè)font-size聲明,這樣的話,p元素的內(nèi)容就出來(lái)。我們的目的只是改變empty元素的繼承自父元素div的字體大小,完美解決~
結(jié)語(yǔ)
???????至此,line-height與vertical-align的性質(zhì)及組合用法就介紹完畢,本文主要參考了張?chǎng)涡翊笊竦摹禖SS深入理解vertical-align和line-height的基友關(guān)系》,如有雷同,不用懷疑,就是受了他的啟發(fā)~
???????文中若有錯(cuò)誤及不妥之處,歡迎指正~
???????本文同時(shí)發(fā)布于博客園https://www.cnblogs.com/keepStudying/p/9520545.html,歡迎圍觀~
???????轉(zhuǎn)載請(qǐng)注明出處,如果不注明出處,給點(diǎn)贊賞也可以哇!要是錢也不給,好吧,你贏了~







