測試代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vertical與line-height測試</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中的定義為行高,具體計算方法如圖所示:
???????由圖中可以看出窄刘,在不設(shè)置元素高度以及padding窥妇、border、margin均為0的情況下娩践,元素本身的高度就是它的line-height值活翩,而文本與文本之間的間隙就是(line-height - font-size)烹骨。所以此時通過設(shè)置line-height值,就等于在設(shè)置元素高度(元素高度不固定且padding材泄、border沮焕、margin不為0時,高度由padding拉宗、border峦树、margin及行高共同控制)。
???????那么旦事,在了解了line-height對元素高度的控制原理之后魁巩,就不難理解文本元素垂直居中的原理,令height=line-height姐浮,或者不設(shè)置height(默認line-height)谷遂,都是通過讓height = (line-height - font-size)/2 + font-size + (line-height - font-size)/2,然后文本居中顯示卖鲤。如果在一個<div>中嵌套一個<p>分別把p元素display: inline-block肾扰、display:line,則為下圖展示的原理:
-
display:block(默認);
p元素與div元素等高且等寬 -
display:inline-block;
p元素與div元素等高蛋逾,與內(nèi)容等寬 -
display::inline;
p元素與內(nèi)容等高且等寬
???????上面三張圖片集晚,分別展示了p在三種元素類型下的不同表現(xiàn)形式,從中可以理解inline-block的工作機理(子元素繼承)换怖,實際上是通過控制高度甩恼,使內(nèi)容(inline)居中,而不是元素本身居中沉颂。那么試想一下,如果在p元素前插入一段純文本悦污,或者P元素是多行文本铸屉,那么div中顯示情況又會如何?圖中的div的height是固定的100px切端,那如果不設(shè)置height的值彻坛,又會如何顯示?踏枣?請各位自己動手進行驗證~
???????另外昌屉,從第一張及第二張圖中還可以看出一個小問題,p元素的邊框溢出了div的盒子茵瀑。通過父元素div設(shè)置固定值height與不設(shè)置固定值時间驮,確定子元素p的height與父元素div的height的計算關(guān)系。希望各位同仁能夠找到自己的答案~
二马昨、vertical-align的性質(zhì)
???????vertical-align從字面上理解就是垂直排列竞帽,這貨有一大堆屬性可寫扛施。不要覺得這貨平常不怎么用,實際上它無處不在屹篓。因為瀏覽器默認設(shè)置中疙渣,inline與inline-block的對齊方式,就是baseline基線對齊堆巧,想要理解各種屬性的對齊方式妄荔,我們先看一下各種屬性的意義,如圖所示:
???????這個圖實在是難畫谍肤,從水印也可以看出來懦冰,我是直接從網(wǎng)上粘過來的,如有雷同谣沸,我選擇刪除(哈哈刷钢,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對齊方式:
1)瀏覽器默認baseline對齊;
2)設(shè)置了middle/baseline的情況下乳附,元素自身middle/baseline會和行內(nèi)其他元素的baseline對齊(一個inline-block元素内地,如果里面沒有inline內(nèi)聯(lián)元素,或者overflow不是visible赋除,則該元素的基線就是其margin底邊緣阱缓,否則,其基線就是元素里面最后一行內(nèi)聯(lián)元素的基線——摘自張鑫旭《CSS深入理解vertical-align和line-height的基友關(guān)系》)举农;
3)設(shè)置了top/bottm情況下荆针,自己的top/bottom會和行內(nèi)其余元素中最高的top/最低的bottom對齊;其余補充:
1)verti-align只可用于inline或inline-block颁糟;
2)vertical-align必須在目標元素中聲明航背,對其他元素不產(chǎn)生影響;
3)vertical-align如果設(shè)置%屬性的話棱貌,以line-height值為計算基數(shù)玖媚;
4)vertical-align默認屬性為baseline;
三婚脱、line-height與vertical-align的搭配使用今魔,元素垂直居中
???????在第一部分最后我說到了,通過line-height達到的居中效果障贸,實際上是子元素繼承了父元素的height與line-height設(shè)置错森,本質(zhì)上是內(nèi)容的居中,而非元素本身的居中篮洁。試想一下涩维,如果div中嵌入的是img而非p元素,如何在一個height設(shè)置了固定值的div中嘀粱,將img垂直居中顯示激挪?辰狡?(這里的固定值,包括從父元素按%計算而來的固定值垄分。未設(shè)置固定高度值的宛篇,高度以內(nèi)容為準,可通過padding-top/bottom或line-height設(shè)置居中)
???????這就涉及到了line-height與vertical-align的配合使用薄湿。
在實際操作前叫倍,首先回憶一下剛才的內(nèi)容:
- line-height通過控制元素高度與其內(nèi)容字體高度的差值均分,實現(xiàn)垂直居中豺瘤;
- vertical-align默認baseline對齊吆倦;
- vertical-align在目標元素中聲明,且目標元素一定是inline或inline-block屬性的元素坐求;
Duang~準備就緒〔显螅現(xiàn)在開始說明操作過程,同樣以圖片直觀的展現(xiàn):
-
當給div一個固定的height值桥嗤,在不設(shè)置line-height及vertical-align時须妻,由于設(shè)置了* {margin: 0;padding: 0;},圖片是緊貼頂端的泛领。
-
讓我們來加一段文字荒吏,讓理解更直觀。此時渊鞋,我們就能看到vertical-align的默認屬性baseline對齊绰更。圖片由于不是文字,它的基線就是它的margin底(此圖中margin為0)锡宋,即border-bottom儡湾。
-
下面讓我們給img屬性增加vertical-align: middle;,可以看出文本與圖片似乎居中對齊了员辩,但是文本呢盒粮,有一點emmmmmm,不那么居中奠滑!因為圖片是以自身的middle line與文本的baseline對齊的。所以實際的中點要在對齊線的上方(詳情上翻至vertical-align的對齊方式)妒穴。
-
設(shè)置div的line-height = height值宋税,去除文字的border(防止子元素p繼承父元素div的高度后,增加border溢出)讼油。此時文本垂直居中顯示杰赛,按照上一步的解釋,不難看出矮台,圖片因為與文本并不是真正的居中對齊乏屯,所以實際上它在div中并沒有真正的垂直居中根时。
-
解決方案
1)那么怎么才能讓圖片真正的垂直居中呢?腦子轉(zhuǎn)的快的朋友肯定已經(jīng)想到了辰晕,可以把p元素也聲明vertical-align: middle;啊蛤迎。這確實是個好方法,但是含友!如果文本設(shè)置了vertical-align后替裆,它自身也并不是垂直居中了的話,那這種方法就不成立了窘问。而且很不幸的是辆童,情況就是這樣(控制臺可查看p元素高度,已經(jīng)溢出div盒子)惠赫。那么為什么會出現(xiàn)這種情況呢把鉴。那就要我們回想一下,如果行內(nèi)只有一個p元素或者一個img元素的話儿咱,它又是跟誰對齊的庭砍?
???????要理解行內(nèi)元素對齊,這里就必須提出一個假設(shè)概疆,假設(shè)block元素內(nèi)逗威,存在一個empty元素。在block元素內(nèi)只嵌套了一個inline或inline-block元素時岔冀,作為規(guī)則的參照物凯旭。而且empty元素雖然看不見,但要假設(shè)它里邊有一個繼承自父元素font-size的文本使套,這樣它才具有正常的baseline罐呼、middle line及top、bottom等侦高。理解了這一假設(shè)嫉柴,就不難理解為什么p元素設(shè)置vertical-align: middle;后,圖片仍然不是垂直居中奉呛。因為p元素中線與empty元素的基線對齊了计螺。
???????那么有的朋友又會提出問題了,既然圖片與文本的基線對齊瞧壮,文本下移了登馒,圖片為什么沒有跟著文本的基線一起下移呢?那是因為基線始終都只有一條咆槽,那就是empty元素的基線陈轿。這也就解釋了,為什么p元素設(shè)置了vertical-align: middle;后,只有p元素下移麦射,而img元素紋絲不動蛾娶。因為p元素與empty元素由baseline對齊baseline變?yōu)榱薽iddle line對齊baseline,造成了下移潜秋,而img元素始終都與empty元素對齊蛔琅,所以紋絲不動。
2)俗話說柳暗花明又一村半等,一條路走不通揍愁,必然有另一條路。既然改變p元素的vertical-align行不通杀饵,那就嘗試其他方法莽囤,比如改變基線的位置。
???????這就需要另一個屬性font-size切距,既然基線由行內(nèi)empty元素的字體大小決定朽缎,那如果我把font-size設(shè)置成0,那不是所有線全都匯聚成了一條谜悟,那么文字的居中顯示话肖,不就變成了這條匯聚線的居中顯示?這樣的話葡幸,跟基線對齊豈不是就成了居中對齊最筒?簡直美滋滋~
???????這樣又有朋友說了,這樣文字就消失不見了蔚叨,一個問題解決了床蜘,又出來個新問題,這什么時候是個頭懊锼邢锯??搀别?別急丹擎,這個方法簡單,那就是給p元素歇父,單獨加一個font-size聲明蒂培,這樣的話,p元素的內(nèi)容就出來榜苫。我們的目的只是改變empty元素的繼承自父元素div的字體大小毁渗,完美解決~
結(jié)語
???????至此,line-height與vertical-align的性質(zhì)及組合用法就介紹完畢单刁,本文主要參考了張鑫旭大神的《CSS深入理解vertical-align和line-height的基友關(guān)系》,如有雷同,不用懷疑羔飞,就是受了他的啟發(fā)~
???????文中若有錯誤及不妥之處肺樟,歡迎指正~
???????本文同時發(fā)布于博客園https://www.cnblogs.com/keepStudying/p/9520545.html,歡迎圍觀~
???????轉(zhuǎn)載請注明出處逻淌,如果不注明出處么伯,給點贊賞也可以哇!要是錢也不給卡儒,好吧田柔,你贏了~