一、line-height的定義
line-height,行高,是指文本行基線間的垂直距離。
1. 什么是基線?
一般而言,一個文本行一共有四條線,從上到下依次為頂線、中線、基線、底線;在英文中,基線為小寫 x 字母下邊緣所在的那條線。如下圖所示:
注意,基線的位置與字體有關,不同的字體基線的位置有偏差。
2. 行高控制行間距。
在多行文本中,第一行文本根據文本的字體和字號顯示,並因此確定了第一行的基線;在此基礎上,根據line-height的值,確定第二行基線的所在位置,在那個位置之上顯示第二行文本。
在這個機制之下,可以推斷出line-height控制行間距,行間距是文本行之間超出字體大小的額外空間。換句話說,line-height與font-size之差就是行間距;如果line-height的值小於font-size,也就是說行間距為負,就會導致后一行文本與前一行文本重疊。
二、行內框與行框
1. 內容區(content area):頂線與底線包圍的區域,其高度與字體和字號相關(可粗略等於font-size的值),與行高沒有半毛錢關系。
2. 行內框(inline boxes):每個行內元素都會生成一個行內框,行內框是一個瀏覽器渲染模型中的一個概念,無法顯示出來,在沒有其他因素影響的時候(比如line-height),行內框等於內容區。
(然而line-height無處不在)設定line-height之后,將半行距【(行高-字體大小)/2】分別增加到內容區的上下兩邊,得到一個行內框。
3. 行框(line boxes):一旦給定的某一行已經生成了所有的行內框,行框的構造就會考慮這些行內框,使行框的高度足以包含最高行內框的頂端和最低行內框的底端。
4. 包含框(containing box):由一行一行的行框組成。
請看如下代碼:

1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>行內框的高度</title> 6 <style> 7 p { 8 font-size: 32px; 9 background-color: orange; 10 width: 500px; 11 margin: 20px auto 50px auto; 12 } 13 14 .p1 { 15 line-height: normal; 16 } 17 18 .p2 { 19 line-height: 20px; 20 } 21 22 .p3 { 23 line-height: 0; 24 } 25 26 ul { 27 font-size: 16px; 28 line-height: 1.5; 29 background-color: cyan; 30 width: 500px; 31 margin: 50px auto; 32 } 33 34 ul>li { 35 padding: 10px; 36 } 37 38 </style> 39 </head> 40 <body> 41 <div> 42 <p class="p1">這是第一個段落,行高為normal。</p> 43 <p class="p2">這是第二個段落,行高為20px。</p> 44 <p class="p3">這是第三個段落,行高為0。</p> 45 </div> 46 <div> 47 <ul> 48 <li>背景顏色為什么會有這些變化?</li> 49 <li>font-size為32px,內容區的高度也就是32px;而line-height為10px,那么半行距就是-11px; 50 將-11px的半行距分別加到內容區的上下部分,從而行內框的高度就變成了10px;行框的高度也相應為10px。</li> 51 <li>當line-height為0,那么半行距就是-16px; 52 將-16px的半行距分別加到內容區的上下部分,從而行內框的高度變成0;行框的高度也相應為0。</li> 53 <li>於是,我們驚奇地發現,在文本行中,line-height決定了行內框的高度,以此為基准確定了行框的高度;因此,行內(文本)元素的高度是由line-height決定的,並不是由元素中的文本撐開的。</li> 54 </ul> 55 </div> 56 </body> 57 </html>
結論:在文本行中,line-height決定了行內框的高度,以此為基准確定了行框的高度;因此,行內(文本)元素的高度是由line-height決定的,並不是由元素中的文本撐開的。
(僅考慮文本的情況,行高=行內框高度=內容區+行間距)
好了,行內框的高度弄清楚了,行高是決定行內框高度的唯一因素,那么行內框的寬度又是怎么確定的呢?
畢竟,行框的構造不僅要考慮最高行內框的頂端和最低行內框的底端,也是要考慮最左邊行內框的左端和最后邊行內框的右端的吧。
在盒子模型中,影響盒子寬度的有內容區的width+padding+border+margin,我們依次來看。
代碼如下:

1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>行內框的寬度</title> 6 <style> 7 p { 8 font-size: 20px; 9 line-height: 1.5; 10 background-color: orange; 11 width: 500px; 12 margin: 50px auto; 13 padding: 20px; 14 } 15 16 span { 17 background-color: red; 18 } 19 20 .p1 span { 21 margin: 30px; 22 } 23 24 .p2 span { 25 margin: 30px; 26 border: 30px solid green; 27 } 28 29 .p3 span { 30 margin: 30px; 31 border: 30px solid green; 32 padding: 30px; 33 } 34 35 </style> 36 </head> 37 <body> 38 <div> 39 <p class="p1"><span>這是</span>第一個段落,紅色區域增加了一個margin屬性,值為30px;可以明顯看到,只有水平方向上的外邊距增加了行內框的寬度,而垂直方向上的外邊距沒有增加行內框的高度。</p> 40 <p class="p2"><span>這是</span>第二個段落,增加了一個30px寬的邊框;可以明顯看到,只有水平方向上的邊框增加了行內框的寬度,而垂直方向上的邊框沒有增加行內框的高度。</p> 41 <p class="p3"><span>這是</span>第三個段落,增加了一個padding屬性,值為30px;可以明顯看到,只有水平方向上的內邊距增加了行內框的寬度,而垂直方向上的內邊距沒有增加行內框的高度。</p> 42 </div> 43 </body> 44 </html>
結論:
行內框在一行中水平排列。可以使用水平內邊距、邊框和外邊距調整行內框的水平間距;但是,垂直內邊距、邊框和外邊距不影響行內框的高度。
三、line-height屬性的值
1. normal;不同的瀏覽器有不同的默認值,且與字體有關,正因為如此,一般會在body元素中reset。
2. number;根據當前元素font-size的值計算。
3. percentage和em。
下面通過一個例子來說明用number、percentage和em的區別:
假設父元素的font-size為20px,line-height為1.5;子元素的font-size為14px;在繼承時,子元素會繼承縮放因子1.5,於是子元素的行高為14*1.5=21px。
假設父元素的font-size為20px,line-height為150%或者1.5em;子元素的font-size為14px;在繼承時,子元素會繼承20*1.5=30px,於是子元素的行高為30。
簡單比較可以發現,使用percentage/em時,繼承的行高是一個計算數值(而且是一個絕對數值,不可變),而使用number時,繼承的是一個縮放因子,使子元素能夠根據自己的字體大小去計算它的行高;很明顯:
設置line-height時使用number靈活性更高。
四、圖像的行內框
以上,我們在討論line-height的時候僅考慮純文本,現在我們來看看圖文混合的情況。
直接上圖,如下:
我們來分析一下:
沒有任何標簽包含的文本,稱為“匿名文本元素”,它們有自己的行內框;
圖像自身有height,上圖中的圖像還有padding、border、margin,可以明顯看出,圖像的行內框高度=height+padding+border+margin;
行框應當包含這一行中最高行內框的頂端(在這里就是圖像的上外邊界)和最低行內框的底端(在這里就是文本的行內框底端);
由於段落的包含框是由它里面所有的行框組成的,這里只有一個行框,這個這個行框就是這個段落的包含框。
總結:文本元素行內框的高度是由line-height決定的,圖像元素的行內框高度是它自己的盒子(height+padding+border+margin)決定的。