【前端Talkking】CSS系列——CSS深刻理解之line-height

1.寫在前面

兩個多周的時間沒有寫文章了,手好癢好癢,趁着公司在裝修,從上週末到本週都在家辦公,同時公司的項目並不緊急,因而抽着時間梳理了一下CSS中關於行高line-height的理解,今天發佈出來,你們準備好了嗎?css

2.基本概念

2.1行高的定義與圖解

行高,顧名思義指的就是一行文字的高度。按照定義來解釋,就是兩行文字之間基線之間的距離。那麼問題來了,什麼是基線呢?你們回想下咱們剛開始學習漢語拼音的時候,使用四線格本子的四條線,其中倒數第二條線就是基線,若是你說,抱歉,我已經所有還給老師了,沒有任何印象。呵呵,別急呢,我已經給你們準備好了,請看下面的這副圖,其中,a、c、e、x、z等字母的底邊線(倒數第二根線)就是咱們說的基線。html

瞭解完基線的定義後,咱們接着來聊行高line-height。上面咱們說過,行高就是兩條基線的之間的距離,以下圖所示。前端

你們是否是已經😓了,你們耐着性子仔細看下,其實挺好理解的:segmentfault

  • 兩條紅線之間的距離就是行高(line-height)
  • 上一行的底線和下一行的頂線之間的距離就是行距,業界的共識是:行距=行高-em-box(暫時理解爲font-size的大小),所以,用CSS語言來解釋行距就是: 行距=line-height-font-size。
  • 同一行頂線和底線之間的距離就是font-size
  • 行距的一半就是半行距

結合上面圖和文字描述,其實能夠很容易搞清楚行高、行距、半行距、font-size的意思。你們必定要弄清楚這些定義,由於,下文中的內容和這些定義有關。windows

2.2 內容區、行內框、行框、包含框

所謂一圖勝千言:瀏覽器

內容區:內容區域能夠近似理解爲FireFox/IE瀏覽器下文本選中帶背景的區域,在上圖中,深灰色背景區域就是內容區域。微信

行內框:每個行內元素都會生成一個行內框,高度等於font-size,當咱們設置line-height的時候,行內框的高度保持不變,改變的是行距的高度。學習

行框:指本行的一個虛擬的矩形框,由本行中的行內框組成。當有多行內容的時候,每一行都有本身的的一個行框。測試

包含框: 包裹着上述三種box的box,暈了,直接看圖吧,上面黃顏色的框就是包含框。字體

3.深刻理解line-height

3.1 line-height的各種屬性值

line-height的默認值是normal,同時還支持數值、百分比值、長度值、繼承。請看下面的表格:

描述
normal 默認。設置合理的行間距。
number 設置數字,此數字會與當前的字體尺寸相乘來設置行間距,即number爲當前font-size的倍數。
length 設置固定的行間距。
% 基於當前字體尺寸的百分比行間距。
inherit 規定應該從父元素繼承 line-height 屬性的值。
  • normal

你們在使用line-height的時候,設置爲該值不多,爲何呢?由於normal是一個與font-family有着密切聯繫的變量值。例如:

div{
    line-height: normal;
    font-family: 'microsoft yahei';
}
複製代碼

div{
    line-height: normal;
    font-family: 'simsun';
}
複製代碼

這兩段代碼在不一樣瀏覽器中測試數據以下:

字體 Chrome Firefox IE
微軟雅黑 1.32 1.321 1.32
宋體 1.141 1.142 1.141

從上面的表格中能夠看到,指定字體後,在不一樣瀏覽器中line-height的解析值基本是同樣的。然而,不一樣的瀏覽器使用的默認字體不同,而且不一樣的操做系統使用的默認字體也是不同的。所以,咱們在實際開發的時候,都須要對行高line-height進行重置操做。

  • inherit

    字面意思是繼承,即繼承父元素line-height的值,父元素是多少,當前節點的line-height就是多少,若是當前節點的子節點不設置任何的line-height,子節點的line-height也是這個值。

  • length

    也就是帶單位的值,好比line-height: 21pxline-height: 1.5em等。若是當前的font-size爲14px,則line-height計算後的值爲1.5*14px=21px

  • number

    例如,line-height: 1.5,最終的計算值是和當前的font-size相乘後的值,好比font-size爲14px,則line-height計算值是1.5*14px=21px

  • %

    例如,當前font-size爲16px,line-height爲120%,則計算後的行高爲16*120%=19.2px

不知道你們發現沒有,line-height:1.5line-height: 150%以及line-height: 150%這三種用法計算的結果 是同樣的,最終計算的行高都是根據font-size來計算的。是否是它們能夠相互替代呢?其實否則,實際上,line-height:1.5和另外兩個的繼承細節有些區別,咱們直接看例子吧。

body{
    font-size: 14px;
    line-height: 1.5;
}
body{
    font-size: 16px;
    line-height: 150%;
}
body{
    font-size: 14px;
    line-height: 1.5em;
}
複製代碼

對於<body>元素而言,上面三種方式計算後的的行高都是21px,可是,若是body下還有子元素,例如:

<body>
    <h3>這是標題</h3>
    <p>這是內容</p>
</body>
複製代碼
h3, p{
    margin: 0;
}
h3{
    font-size: 32px;
}
p{
    font-size:  20px;
}
複製代碼

最終結果是line-height: 150%line-height: 1.5em的最終表現是兩行文字重疊到了一塊兒,以下圖:

而設置了line-height:1.5的最終表現是兩行文字沒有重疊,排版良好,效果以下圖:

設置line-height: 150%line-height: 1.5em後,子元素繼承的是計算後的值,即21px,而不是繼承150%和1.5em,因此<h3><p>的行高都是21px,而<h3>的font-size是32px,則根據上面的公式計算出來的半行距是-5.5px,所以,兩行文字發生了重疊。

不一樣屬性下的line-height最終的計算方式比較以下。

設置方式 line-height 計算後的line-height 子元素繼承的line-height
inherit 父元素的line-height值 不用計算 父元素的line-height值
length 20px 不用計算 20px
% 150% 自身font-size (14px) * 150% = 21px 繼承父元素計算後的line-height值 21px,而不是150%
normal 假如爲1.2 自身font-size (16px) * 1.2 = 19.2px 繼承1.2,line-height = 自身font-size(32px) * 1.2 = 38.4px
純數字 1.5 自身font-size (14px) * 1.5 = 21px 繼承1.5,line-height = 自身font-size(32px) * 1.5 = 48px

因此,在實際開發中, 咱們通常設置行高的值爲 `純數字是最推薦的方式,由於其會隨着對應的 font-size 而縮放,排版效果良好。

3.2 line-height的"大值特性"

如今,請你們仔細閱讀下面的代碼:

<div class="box">
    <span>這是內容...</span>
</div>
複製代碼
.box{
    line-height: 50px;
}
.box span{
    line-height: 10px;
}
複製代碼

.box{
    line-height: 10px;
}
.box span{
    line-height: 50px;
}
複製代碼

拋出問題:請問div的高度是多少?直接上正確答案:都是50px。請看圖

感受說不通啊,那麼請看解釋吧。

首先,咱們要始終記着,內聯元素前面有一個看不見的"幽靈空白節點",所以,上面的html代碼能夠等價爲:

<div class="box">
    幽靈空白節點<span>這是內容...</span>
</div>
複製代碼

因此,當.box元素設置line-height:50px的時候,"幽靈空白節點"高度爲50px,而當.box元素設置line-height: 20px的時候,span元素的高度變成了50px,而又由於行框盒子是由高度最高的那個內聯盒子決定的,因此.box元素的高度永遠是最大的那個line-height的緣由,根據張鑫旭老師的總結,這能夠稱爲line-height的大值特性,不知道這樣解釋你們清楚了沒有呢?

3.3 line-height與內聯元素"垂直居中"

  • 行高讓單行文字"垂直居中"

不知道你是否和我同樣,在剛開始寫CSS的時候,控制單行文字垂直居中的時候,設置line-heightheight的值同樣就能夠實現文字垂直居中的效果,即:

.title{
    height: 50px;
    line-height: 50px
}
複製代碼

其實,這裏只須要保留line-height這個屬性就能夠了,徹底沒有任何須要設置height的大小。

<div style="height: 50px; background-color: #cd0000; color: #fff">
    <span style="line-height: 50px">元素元素元素</span>
</div>
複製代碼

所以,流傳比較廣的"設置line-heightheight的值同樣就能夠實現文字垂直居中效果", 應該修改成:把line-height設置爲您須要的box的大小能夠實現單行文字的垂直居中

  • 行高讓多行文字「垂直居中」

多行文字垂直居中效果須要藉助line-height的好朋友的幫助才能實現,代碼以下:

<div class="box">
    <div class="content">基於行高是實現的多行文本垂直居中...我發現文字很短,因而隨便寫了一點文字湊個數..</div>
</div>
複製代碼
.box{
    line-height: 120px;
    background-color: #cd0000;
    color: #fff;
}
.content{
    display: inline-block;
    line-height: 20px;
    margin: 0 20px;
    vertical-align: middle;
}
複製代碼

效果圖以下所示:

實現的原理以下:

  1. 多行文字使用一個標籤包裹,同時設置display: inline-block,保持了內聯元素的特性,使元素具備單行效果,該設置使元素造成了一個很是關鍵的"行框盒子",而每個行框盒子都會附帶一個"幽靈空白節點"(寬度爲0,可是表現和普通字符相同)。而咱們設置了外層的line-height: 120px,所以,.content內容"幽靈空白節點"的line-height也將是120px;
  2. 內聯元素默認是基線對齊的,經過設置vertical-align:middle能夠實現咱們想要的"垂直居中"效果。

3.4 真的是"垂直居中"嗎

不知道你們有沒有留意上文中的單行文本和多行文本的垂直居中都加了引號,難道還不是真正的垂直居中?沒錯,line-height實現的垂直居中效果只是近似的垂直居中。爲何是"近似"?咱們拿一個例子說明問題:

<p>微軟雅黑</p>
複製代碼
p{
    font-size: 80px;
    line-height: 120px;
    background-color: #cd0000;
    color: #fff;
    font-family: "Microsoft YaHei";
}
複製代碼

在瀏覽器中(windows系統)的效果以下:

你們看到沒有,這些文字的位置明顯偏下。由於,有些字體的位置偏下,好比"微軟雅黑",在平時咱們使用的過程當中,字體大小基本在16~18px之間,雖然下沉,可是也就是1px的誤差,咱們的肉眼根本察覺不到。所以,使用line-height實現的"垂直居中"並非絕對的垂直居中

同理,使用line-heightvertical-align實現的多行文本垂直居中也不是絕對的垂直居中,在上文中多行文本垂直居中的例子中,咱們能夠明顯的看到字體位置偏下。

其實,不居中並非line-height致使的,而是他的好基友vertical-align形成的,咱們會在vertical-align文章中詳細闡述,敬請期待。

4. 最後

關於line-height的介紹就到這裏了,平時咱們應該多思考,多總結,纔會有新的體會。之後個人最新文章都會第一時間更新在公衆號<前端Talkking>裏面,歡迎你們關注。

以上就是本文的所有內容,感謝閱讀,若是有表述不正確的地方,歡迎留言指正!😄

ps:這兩天是一年一度的高考,想一想本身的高考差很少過去了10年了,而如今本身好像沒有什麼成就,想一想好慚愧,努力吧,少年!!!

參考


碰見了,不妨關注下個人微信公衆號「前端Talkking」

相關文章
相關標籤/搜索