一個由line-height引發的血案與思考

knag發表於2019-03-04

爆炸

  最近UI走查,發現頁面中所有包含文字區塊的高度與設計稿中的高度完全不一致,然後UI妹子就爆炸了!

  找了一下原因,發現是由於UI設計稿中設計的文字大部分是font-size:24px;line-height:24px,程式碼實現時為了不至於每處都寫一遍字型大小,故直接在根節點上統一設定字型與字型大小為24px,小部分不一致的地方再單獨設定字型大小,從而忽略了設定line-height為字型的高度。造成的結果就是文字所在的行的行高高於設計稿中的行高。

為什麼文字行高與字型大小不相等呢?

  翻了一下line-height的官方說明,如下所示:

一個由line-height引發的血案與思考

  文件裡說line-height的預設值為normal,給normal的推薦設定值為1.0到1.2之間。相當於如果設定了字型的大小而不設定line-height,那麼行高預設就為字型的1.0-1.2之間的一個倍數。

  那麼,這個倍數到底具體是多少呢?

  在chrome的控制檯裡跟蹤了一下,看到專案中引入了normalize.css來初始化瀏覽器的預設css樣式。其中,就設定html的line-height1.15

為什麼normalize.css設定line-height預設為1.15?

  翻了一下github中normalize.css的issues,在593號issues裡找到了答案,地址在這裡

  大致過程是這樣的,有人發現相同字型與大小的文字在不同環境中line-height的值是不一致的,接著,就有人在crossbrowsertesting上做了個測試,得出的結論就是這個問題的的確確存在,而且差異還特別大

When the font size was 100px, the most common line height was 115px. However, results varied from 101px on Mac Firefox to 136px on Android Chrome.

  最終,由於大部分的行高都為115px,所以,為了解決不同環境中相同字型與字號的文字行高不一致的問題,推薦設定預設line-height為1.15

  看到這裡,想到一個問題,既然顯示設定line-height為1.15是為了解決環境相容的問題。那麼,為什麼不設定line-height:1即解決相容問題,又解決由於行高放大與UI設計稿不符的問題?

設定overflow:hidden字型顯示不全的問題

  當設定文字line-height:1後,再設定文字所在的容器overflow:hidden很容易復現文字顯示不全的問題,比如下面:

dphyTxg

程式碼如下:

<span style="
font-size:100px;
line-height:1;
overflow:hidden;
border:1px solid #ddd;
display:inline-block">dphyTxg</span>
複製程式碼

注:這裡可以使用div演示,然後去掉display:inline-block。使用div發現不知道為毛markdown裡的樣例亂了...

為什麼設定行高與字型大小一致文字會顯示不全?

  到這裡,才真正進入到深層次的原因探究。

  對於這個問題,需要先了解字型度量,引用一下其它的文章說明,如下所示:

一個由line-height引發的血案與思考

  1. 原文地址
  2. Deep dive CSS: font metrics, line-height and vertical-align
  3. EM Square
  4. FontForge

簡要解釋為如下幾點:

  1. 我們設定font-size的高度實際上是對應字型的EM square部分
  2. 字型在設計時可以超出EM square部分
  3. 字型實際設計與EM square部分一致時,line-height:normalline-height:1相等
  4. 從上圖中可以看到,ascender+descender>Em Size1100+540>1000,此時line-height:1.64,所以100px的文字預設的行高為164px

樣例分析

  下面就以window環境下的預設字型微軟雅黑為例實際看看line-height的計算。

h1

line-height:

程式碼如下:

<h1 id="font" style="line-height:normal;font-size: 100px;font-family: 微軟雅黑">h1</h1>
<p>line-height: <code id="o1" style="font-size: 50px"></code></p>
<script>
  document.getElementById('o1').textContent = window.getComputedStyle(document.getElementById('font')).height;
</script>
複製程式碼

  從上面可以看到微軟雅黑100px情況在,在windows下行高顯示為132px。通過FontForge來核對一下看看是不是這樣的。

一個由line-height引發的血案與思考

  從上圖中可以看到,使用(ascender+descender)/Em Size,即(2167+536)/2048≈1.32,也就是line-height為1.32.

結論

  1. line-height:normal的值跟字型有關係,相同字型在不同環境也不一樣
  2. 當line-height設定的值小於預設的值時就會存在顯示不全的問題
  3. normalize.css設定line-height預設為1.15,當字型line-height的normal大於1.15就會存在文字顯示不全的問題
  4. 要解決字型在不同平臺line-height不一致的問題,需根據具體字型,選擇normal在不同平臺上的最大值設定

一個由line-height引發的血案與思考

相關文章