深入淺出CSS(一):line-height與vertical-align的性質(zhì)

測(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,則為下圖展示的原理:

  1. display:block(默認(rèn));


    p元素與div元素等高且等寬

  2. display:inline-block;


    p元素與div元素等高,與內(nèi)容等寬

  3. 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)

  1. 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;

  2. 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ì)齊;

  3. 其余補(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)容:

  1. line-height通過(guò)控制元素高度與其內(nèi)容字體高度的差值均分,實(shí)現(xiàn)垂直居中;
  2. vertical-align默認(rèn)baseline對(duì)齊;
  3. vertical-align在目標(biāo)元素中聲明,且目標(biāo)元素一定是inline或inline-block屬性的元素;

Duang~準(zhǔn)備就緒?,F(xiàn)在開始說(shuō)明操作過(guò)程,同樣以圖片直觀的展現(xiàn):

  1. 當(dāng)給div一個(gè)固定的height值,在不設(shè)置line-height及vertical-align時(shí),由于設(shè)置了* {margin: 0;padding: 0;},圖片是緊貼頂端的。

  2. 讓我們來(lái)加一段文字,讓理解更直觀。此時(shí),我們就能看到vertical-align的默認(rèn)屬性baseline對(duì)齊。圖片由于不是文字,它的基線就是它的margin底(此圖中margin為0),即border-bottom。

  3. 下面讓我們給img屬性增加vertical-align: middle;,可以看出文本與圖片似乎居中對(duì)齊了,但是文本呢,有一點(diǎn)emmmmmm,不那么居中!因?yàn)?strong>圖片是以自身的middle line與文本的baseline對(duì)齊的。所以實(shí)際的中點(diǎn)要在對(duì)齊線的上方(詳情上翻至vertical-align的對(duì)齊方式)。

  4. 設(shè)置div的line-height = height值,去除文字的border(防止子元素p繼承父元素div的高度后,增加border溢出)。此時(shí)文本垂直居中顯示,按照上一步的解釋,不難看出,圖片因?yàn)榕c文本并不是真正的居中對(duì)齊,所以實(shí)際上它在div中并沒(méi)有真正的垂直居中。


  5. 解決方案
    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)贊賞也可以哇!要是錢也不給,好吧,你贏了~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 參考文章:深入了解CSS的line-height屬性Vertical-Align: 你需要知道的所有事【譯】Ver...
    若邪Y閱讀 3,566評(píng)論 1 6
  • 問(wèn)答題47 /72 常見(jiàn)瀏覽器兼容性問(wèn)題與解決方案? 參考答案 (1)瀏覽器兼容問(wèn)題一:不同瀏覽器的標(biāo)簽?zāi)J(rèn)的外補(bǔ)...
    _Yfling閱讀 14,154評(píng)論 1 92
  • 1. 前言 前端圈有個(gè)“梗”:在面試時(shí),問(wèn)個(gè)css的position屬性能刷掉一半人,其中不乏工作四五年的同學(xué)。在...
    YjWorld閱讀 4,917評(píng)論 5 15
  • 為人父母,平時(shí)的一言一行都無(wú)形中給孩子傳遞著自己的生活觀,價(jià)值觀。 這些潛移莫化的影響,最終決定了孩子的生活觀,價(jià)...
    __702b閱讀 242評(píng)論 0 0
  • 我家門口有棵還算大的泡桐樹,每年春天花期到了,打開窗戶就能聞到那一層層的粉粉香氣。 小時(shí)候總是時(shí)間多些,花開了就在...
    武逸文閱讀 509評(píng)論 0 0

友情鏈接更多精彩內(nèi)容