什麼是字號大小?字號大小就是字體的高度,例如設置字號爲50px,那麼它的高度以下圖所示:css
什麼是行距呢?以下圖所示:html
其中半行距 = (lineHeight – fontSize) / 2。chrome
可是實際上,font-size常常不等於渲染的高度,以下圖所示:瀏覽器
對於筆者用的ProximaNova這個字體,設置font-size爲30px,實際上高度爲42px。爲何文字的高度不等於字號的高度?這得從字體設計提及。爲此裝了一個FontForge和RoboFont軟件設計一款本身的字體。bash
打開RoboFont,以下圖所示:(這個軟件常常閃退,須要注意保存)dom
雙擊l和y兩個字母,用鋼筆工具勾勒形狀,以下圖所示:工具
從上圖能夠看到它有一些刻度和度量線,畫一個示意圖以下所示:字體
這些度量線的位置能夠本身設置:ui
Units Per Em表示一個字的高度有1000個單位,baseline的座標爲0,其它線的座標相對於baseline,以下圖所示:url
而後把這個設計好的字體導出爲my-font.ttf文件,在網頁經過@font-face引入,以下代碼所示:
@font-face {
font-family: 'my-font';
src:url('/Users/yincheng/Desktop/my-font.ttf');
font-weight: normal;
font-style: normal;
}複製代碼
而後使用這個font-family,你會發現,這個字體的font-size和height幾乎徹底一致,以下圖所示,分別設置font-size爲35px、45px、55px:
爲何咱們設計的字體會如此「完美」,而其餘人的字體高度老是要大一點呢?
爲此咱們用FontForge打開ProximaNova.ttf,由於這個軟件能夠查看字體的更多信息,就是界面醜了點。以下圖所示:
而後點擊Element -> FontInfo,切到OS/2的Metric標籤,以下圖所示:
把鼠標放到相應的輸入框,FontForge會提示你Windows系統是使用Win Descent和Ascent決定字體內容高度,而Mac是用的HHead Descent和Ascent。上面字體在Mac下的Ascent爲1079,Ascent爲-336,以下圖所示:
同時它的units of em仍然是1000,以下圖所示:
而它的內容區域content-area大小爲1079 - (-336) = 1415是font-size 1000 unit的1415 / 1000 ~= 1.4倍,這就解釋了一開始提出的問題:
設置font-size爲30px,實際上顯示42px,由於30 * 1.4 = 42px,爲進一步驗證,把咱們設計的字體my-font改一下它的Ascent,以下圖所示:
這樣它的內容區域高度就變成了1250unit,是字號大小的1.25倍,導出爲一個新的字體,在網頁上使用,以下圖所示:
設置font-size爲50px,它的content-area高度爲50 * 1.25 = 62.5px。這就證實了上面的分析是對的。
那麼爲何設計師們要這樣搞呢,爲何不控制在1000個unit的範圍內?首先由於經常使用的unit per em爲有如下幾個值:
若是你的unit選得越大,那麼曲線的光滑粒度可控制得更細,以下圖所示:
可是若是選1000的話,由於它是一個整千,比例什麼的應該會比較好控制。
其次,大於1000可讓可控制的區域更大,通常不會讓字恰好撐到底線和頂線,以下圖所示:
能夠在RoboFont裏面設置每一個字的寬度,例如y這個字母我要讓它比z佔的空間小一點,以下圖所示:
y爲400,z爲500,也就是說y的寬度爲高度的0.4,z的寬度爲高度的0.5,由於高度是1000.
font-size爲50px的時候,4個yz的寬度爲180px,以下圖所示:
由於:(50 * 0.4 + 50 * 0.5) * 4 = 180px。
再討論一個經典的問題。
有如下html:
<div style="border:1px solid #ccc"><img src="/Users/yincheng/Desktop/2.png"></div>
在瀏覽器下面顯示爲:
複製代碼
爲何圖片不是和div底部貼在一塊兒,而會有一點空白呢?
先來看一下這個空白有多大,以下圖所示,設置div的font-size爲40px,line-height爲60px:
div的高度爲174,圖片的高度爲154,所以這裏空白的高度爲174 - 154 = 20px。
爲了輔助說明,在img的後面跟上幾個字母,以下代碼所示:
<div class="img-container"><img src="/Users/yincheng/Desktop/2.png">lyz</div>
畫上輔助線:
複製代碼
複製代碼
這段空白的距離就是基線baseline到div底邊的距離。因爲基線的座標是0,底線的座標爲-250,因此基線到底線的距離爲:
250 / 1000 * 40 = 10px
因爲行高爲60px,font-size爲40px,因此底線到div的距離即半行距爲:
(60 - 40)/ 2 = 10px
所以基線到div底邊的距離就爲:
10px + 10px = 20px
到這裏就解釋了爲何會有空白,以及空白的大小怎麼計算。
那怎麼去掉這段空白呢,能夠設置div的行高爲0。而且須要注意的是在怪異模和有限怪異模式下,爲了計算行內子元素的最小高度,一個塊級元素的行高必須被忽略,因此即便不設置div的行高爲0,圖片也是和div貼在一塊兒的。這個咱們在《從Chrome源碼看瀏覽器如何構建DOM樹》討論過。
參考: