在學習css期間,不少同學感覺基本能理解line-height和vertical-align的用法,但是遇到一些具體問題的時候,又發現搞不太明白了,這主要是對一些相關概念理解得還不夠透徹,今天我們就通過本文一步步幫大家徹底搞懂這2個概念。
一、相關概念
要理解line-height和vertical-align這2個概念,我們同時也要掌握一些相關的概念,下面我們就給大家一一介紹。
1.1 內聯盒子
塊狀元素的每一行,就是由內聯盒子組成的,內聯盒子分為具名內聯盒子和匿名內聯盒子。
* 如果被行內元素包裹,屬于具名內聯盒子。
* 如果只是光禿禿的文字沒有被行內元素包裹,屬于匿名內聯盒子。
我們來具體舉個例子:
div {
width: 400px;
font-size: 30px;
background-color: gold;
}
span {
background-color: yellowgreen;
}
<div>今天的<span>月亮</span>好美??!</div>
頁面展示效果如下:

黃色背景是一個p標簽,它的一行包含了:①光禿禿的文字“今天的”;②一個行內元素“<span>月亮</span>”;③光禿禿的文字“好美??!”。其中①和③就屬于匿名內聯盒子,②屬于具名內聯盒子。
這里我們再對比一下2種內聯盒子的高度:
上例中,我們知道div的高度height是由匿名內聯盒子和具名內聯盒子的高度撐起的行高決定的,顯示為40px:

現在我們在瀏覽器端把span標簽的文字大小改成0,那么此時div完全是由具名內聯盒子撐起的行高,我們看到div高度同樣是40px。

因此我們可以得出結論,不論是具名內聯盒子還是匿名內聯盒子,它們的空間高度是由字體大小決定的,兩者沒有區別。所以當我們需要查看內聯盒子效果時,可以用span標簽來表示,因為其可以設置背景色會更直觀。
1.2 行框盒子
塊級元素的每一行就是一個行框盒子,每個行框盒子又是由一個一個內聯盒子組成的。行框上邊界要包裹住所有內聯盒子的上邊界,行框的下邊界要包裹住所有內聯盒子的下邊界。

在瀏覽器中,我們用光標選中一行的效果,即下圖里的整個藍色區域就是一個行框盒子的區域(注意:此種情況只適用于自然撐開的高度,設置行高拉開的距離,藍色區域會大于行款盒子高度)。

1.3 基線
基線是內聯盒子中小寫字母的x的下邊緣的一條線,為了垂直方向對齊用的。
默認情況下,行框盒子內的所有元素都是相對父元素在垂直方向上基線對齊。
舉例如下:

上面三個”xx“,其中第一個①是直接寫在父元素div標簽里的,②③是分別寫在2個span標簽里,默認情況下span標簽里的內容在垂直方向上會與①里的x的底邊對齊。
這里要注意,即使標簽里寫的不是小x,也有小x這樣的一個空間對齊概念存在。為了幫助大家更好理解,上例中,我們把div里寫的“xx”去掉了,顯示效果如下:

我們可以看到,兩個span標簽垂直方向的位置依然沒有變化。
1.4 幽靈節點
在html5文檔聲明中,內聯元素的所有解析和渲染就像每行行框盒子前面有一個空白節點,這個節點是透明的,沒有任何寬度,也沒有辦法用腳本獲得(幽靈節點)。但是它只在使用html5文檔聲明的時候才存在。
我們寫下如下代碼:
<!DOCTYPE html>
<style>
body {
margin: 0;
background-color: gold;
}
#box {
width: 1200px;
padding: 0 50px;
margin-top: 20px;
font-size: 100px;
background-color: black;
}
span {
background-color: yellowgreen;
}
img{
width: 100px;
}
</style>
<div id="box">
<img src="./233.png" alt="">
<span>中文aljx字符</span>
</div>
頁面的展示效果如下,我們看到圖片底邊和span標簽的文字x底邊存在對齊現象,因此,拉高了行高,圖片底邊和div底邊沒有重合。

現在我們在瀏覽器端設置span標簽的字體大小為0,效果如下:

我們看到,div依然和上面顯示span標簽時撐開了相同的高度,這是由于div自己的字體大小是100px,不論其中是不是直接寫了文字,div里的圖片也會有基線對齊的情況,不過圖片是以其底邊和父元素里的x底邊對齊。
只有當我們把div的字體設置為0時,才能解決這個問題:

二、line-height和vertical-align
2.1 line-height
上面我們學習了行框盒子,line-height就是來設置每行之間的距離。
首先大家要明確,因為行框盒子是存在于塊狀元素當中,所以這個行高屬性line-height也是給塊元素設置的。注意:line-height具有繼承性,其后代的塊狀元素都會繼承該屬性。
格式:line-height:value
value取值:
(1)normal,默認值。不設置此屬性的時,是通過瀏覽器自動去計算。
(2)length,長度。使用指定長度作為行高值。單位px,em等。
(3)number,數值。此時表示設置為當前字體大小的number倍的值。大多數情況下,這是設置line-height的推薦方法,不會在繼承時產生不確定的結果。
(4)%,百分比。該值是相對于當前字體尺寸的百分比來設置間距。
(5)inherit。從父元素繼承line-height屬性的值。我們知道line-height本身就具有繼承性,為何還有有這個繼承的屬性值呢?這個屬性值是針對如input標簽這種有自己樣式的標簽使用的,如input標簽的line-height值默認是normal,不會從父元素繼承,而希望該值和父元素的行高一致就需要設置為該屬性值。舉例如下:
這是沒有設置該屬性時的默認效果:

這是line-heigh設置為inherit的效果:

應用舉例:
(1)在沒有設置塊狀元素高度的時候,其高度是由line-height決定的。
①line-height值不為0時,代碼如下:
<style>
#box1 {
width: 200px;
line-height: 50px;
background-color: gold;
border: 1px solid black;
}
</style>
<div id="box1">看看div高度</div>
此時的div高度為50px,如下圖:

②line-height值為0時,代碼如下:
<style>
#box1 {
width: 200px;
line-height: 0;
background-color: gold;
border: 1px solid black;
}
</style>
<div id="box1">看看div高度</div>
此時div高度為0,如下圖:

(2)line-height可以讓內聯元素近似居中(適用于當line-heigh大于內聯元素自身高度的情況)。
我們來看以下代碼:
<style>
body {
background-color: gold;
}
#box {
width: 1200px;
padding: 0 50px;
font-size: 80px;
line-height: 150px;
background-color: black;
}
span {
background-color: yellowgreen;
}
</style>
<div id="box">
<span>中文aljx</span>
</div>
顯示效果如下:

我們可以看到①②的高度是一致的,所以此時span標簽位置在div中是正好居中的,但是由于CSS字體在設計的時候不會正好占據內聯盒子內容區的1/2處,一般來說會有一些下沉,所以文字顯示效果是近似居中的。
2.2 vertical-align
上面講到的幽靈節點,我們知道了一個默認基線對齊的現象,那我們要如何消除幽靈節點的影響呢,設置vertical-align屬性,來調整內聯盒子在一行中垂直怎么對齊,就是一個解決方案。注意,這個屬性是設置給需要修改對齊方式的行內/行內塊元素的。
格式:vertical-align:value
value取值:
* baseline(基線),默認值?;€是內聯盒子中小寫字母的x的下邊緣的一條線與和父元素的x下邊緣線對齊。
* middle,元素的垂直中心點和父元素的x的1/2處對齊。
* bottom,內聯盒子的底部和行框的底部對齊。
* top,內聯盒子的頂部和行框的頂部對齊。
說明:(1)設置為baseline或middle時,都是與父元素里的子文本節點x位置有關,即使沒有寫x也存在這樣一個空間概念,可以理解為以下書寫:
<div>
x // baseline或middle時都是以這個x為標準對齊,即使沒有寫它,也會有這么一個空間概念
<span>xxx</span> // span標簽里的內容是以父元素div里的x為對齊標準
</div>
(2)設置為top或bottom時,只與行框盒子的上下邊界有關,與父元素中的x不再有關。舉例如下:
<style>
body {
background-color: gold;
}
#box {
width: 1200px;
padding: 0 50px;
font-size: 100px;
color: white;
background-color: black;
}
span {
vertical-align: bottom;
color: black;
font-size: 50px;
background-color: yellowgreen;
}
</style>
<div id="box">
中文aljx
<span>中文aljx</span>
</div>
顯示效果如下:

我們已知行框盒子上、下邊界要包裹住所有內聯盒子的上、下邊界,此時白色字體的匿名內聯盒子高度撐起行框盒子的上下最大高度,設置span標簽以bottom垂直對齊,其底邊就與行框盒子的底邊在一條線上。
2.3 line-height和vertical-align的具體應用
(1)設置圖片垂直居中。
<!DOCTYPE html>
<html>
<head>
<style>
div {
width: 500px;
height: 500px;
border: 1px solid black;
text-align: center;
/* 1.設置line-heihgt=height */
line-height: 500px;
}
img {
/* 2.設置圖片居中 */
vertical-align: middle;
}
</style>
</head>
<body>
<div>x<img src="./233.png" alt="" /></div>
</body>
</html>
顯示效果如下:

如果單獨設置line-height和height高度一致并不能使圖片垂直居中,因為圖片底邊會和父元素里的x底邊對齊,所以要要實現圖片垂直居中,這2個屬性需要配合使用。
(2)設置多行文本垂直居中。
<!DOCTYPE html>
<html>
<head>
<style>
div {
width: 300px;
height: 300px;
/* 1.設置line-height=height */
line-height: 300px;
border: 1px solid black;
}
span {
/* 2. 去設置span讓span變成行內塊狀元素,這樣就能將span當成一個整體來對待 */
display: inline-block;
border: 1px solid green;
/* 3.line-height具有繼承性需要將其繼承下來的line-height去掉 */
line-height: normal;
/* 4.讓span和父元素的x的1/2處對齊 */
vertical-align: middle;
}
</style>
</head>
<body>
<div>
<span>
你的眼睛可真好看,里面有晴雨,日月,山川,江河,云霧,花鳥……但我的眼睛更好看,因為我的眼里,有你。——余光中
</span>
</div>
</body>
</html>
顯示效果如下:

上面我們有舉例說明單獨設置line-height可以實現單行的文本垂直居中,但是這種多行文本的垂直居中,我們就需要配合vertical-align: middle來實現垂直居中效果。
總結
在具體的運用中,要實現單行文本的垂直居中,設置line-heihgt與height的值相同就可以實現。但如果要實現圖片或多行文本的垂直居中,我們就需要將line-height與vertical-align一起共同使用才能實現居中效果。






