什麼是 font-weight ?了解 font-weight 在前端的應用

什麼是 font-weight

font-weight 的屬性值有 100、200、300、400、500、600、700、800、900 和 normal、bold、lighter、bolder,它們的區別是什麼?另外,在實際開發中,我們應該使用數值表達還是文字表達呢?

認識 font-weight

根據 W3C Fonts 節章的規範標準,可知:

w3c_fontWeight.jpg

font-weight 可取值:100~900 和 normal、bold、bolder、lighter。


100~900、normal、bold

如果字體使用九階有序數值 100~900 來劃分其字重(字體的粗細度),那麼樣式指定的 font-weight 屬性值與字體的字重則一一對應。並且 normal 等價於 400,bold 等價於 700。但實際上,我們一般遇到的字體很多時候都是使用一些通用的詞描述劃分其字重,如下所示。

常見的字重數值大致對應的字重描述詞語:

  • 100 - Thin
  • 200 - Extra Light (Ultra Light)
  • 300 - Light
  • 400 - Regular (Normal、Book、Roman)
  • 500 - Medium
  • 600 - Semi Bold (Demi Bold)
  • 700 - Bold
  • 800 - Extra Bold (Ultra Bold)
  • 900 - Black (Heavy)

為什麼說大致對應呢?在有些字庫下是有差異的,比如在 Adobe Typekit 字庫中對字重描述的劃分列表中,它列出 Heavy 指的是 800 而不是 900。另外,在我們日常使用的 Photoshop 和 Sketch 裡面,Ultra Light 是 100,而 Thin 是 200。

並且,字體所擁有的字重的數量實際上很少存在滿足有 9 個字重剛好跟 100~900 的 CSS 字重一一對應的情況,通常字體擁有的字重數量為 4 至 6 個。不必擔心,起碼 400 和 700 對應的字重至少是每種字體必備的,譬如常見的 Arial、Helvetica、Georgia 等等,只有 400(normal) 和 700(bold)。


bolder、lighter

bolder、lighter 表示其字重值是基於從其父元素繼承而來的字重計算所得的,與 normal、bold 所代表的字重並無關係。

其值通常是根據下表計算而得的:

繼承值(Inherited value) bolder 所代表的字重 lighter 所代表的字重
100 400 100
200 400 100
300 400 100
400 700 100
500 700 100
600 900 400
700 900 400
800 900 700
900 900 700

 


字體匹配算法

在上面我們已經提到,在很多情況下,字體並不是以九階數值來劃分的,並且其含有的字重數量是不一的,通常情況下為 4-6 個。

此時,就會出現樣式指定的字重數值在字體中找不到直接對應的字重,那瀏覽器是如何解決的呢?

Bingo!那就是要靠字體匹配算法來解決。其中關於 font-weight 部分是這麼提及到的:

fontMatching.jpg

講人話就是:如果指定的 font-weight 數值,即所需的字重,能夠在字體中找到對應的字重,那麼就匹配為該對應的字重。否則,使用下面的規則來查找所需的字重並渲染:

  • 如果所需的字重小於 400,則首先降序檢查小於所需字重的各個字重,如仍然沒有,則升序檢查大於所需字重的各字重,直到找到匹配的字重。
  • 如果所需的字重大於 500,則首先升序檢查大於所需字重的各字重,之後降序檢查小於所需字重的各字重,直到找到匹配的字重。
  • 如果所需的字重是 400,那麼會優先匹配 500 對應的字重,如仍沒有,那麼執行第一條所需字重小於 400 的規則。
  • 如果所需的字重是 500,則優先匹配 400 對應的字重,如仍沒有,那麼執行第一條所需字重小於 400 的規則(感謝 @淺夏莜韻的指正)。

感謝來自 @何洋的補充:
大多數瀏覽器已實現 font-synthesis 屬性,使用該屬性可以控制在 font-weight 沒有相匹配的 font typeface 時,會模擬計算出合適的渲染字重 (與其應有的 typeface 有些差異),從而忽略 Font Matching Algorithm。
參考文章:


理解與運用

下面我們通過官方例子和實際測試來好好理解這個匹配算法規則。

官方例子

W3C 規範標準中給出這麼一個例子:

font_matching_examples.jpg
註解:灰色標記的是字體中缺少的字重,而黑色則是字體擁有的字重。

基於匹配算法規則,看圖理解所得:

Figure 15. 圖指的是

字體庫內直接匹配的字重 填空值 (即通過算法間接匹配所得字重)
400 300、200、100、500
700 600
900 800

font-weight: 300; 來說,字體中沒有可以直接匹配的字重,那麼 300 小於 400,則根據第一條規則,先降序查找匹配,但是都沒有可匹配的 200、100,那麼升序查找為 400,結果可匹配。

Figure 16. 圖指的是

字體庫內直接映射的字重 填空值
300 200、100、400、500
600 700、800、900

這裡需要注意的是,填空值 500 表現的是 300 的字重,而不是 600 的字重。
為什麼呢?根據規則,500 優先匹配 400 的字重,但是此處找不到 400 的字重,則執行規則中第一條所需字重小於 400 的情況。

其餘的,我就不多解釋了,大家可以根據結果檢查自己是否理解到位。

實際測試——Droid Sans

googlefonts.jpg

根據 Google Fonts API - Droid Sans 提供的 Droid Sans 字體,我們可以知道該字體擁有兩種字重。

根據字體匹配算法規則,我們可以預測其字重匹配應該如下表所示:

字體庫內直接映射的字重 填空值
400 300、200、100、500
700 600、800、900

也就是 100、200、300、500 會表現為跟 400 同一種字重,600、800、900 會表現為跟 700 同一種字重。

利用 Google Fonts 提供的 Droid Sans,我們進行了實例測試-(DroidSans.html) 來驗證。
結果如下圖,證明我們的預測結果正確,該字體匹配算法規則運行有效。

droid_sans_res.jpg


總結

根據以上的研究,可以總結出三點:

  1. 通常情況下,一個特定的字體僅會包含少數的可用字重。若所指定的字重不存在直接匹配,則會通過字體匹配算法規則匹配使用鄰近的可用字重。這也就是為什麼我們有時候使用特定字重時沒有「生效」,看起來跟其它字重差不多的原因所在。
  2. 在實際中,最為常用的字重是 normal 和 bold。我個人認為 400、700 是等效於 normal、bold 的,無論哪一種表示方法都沒有關係,主要是個人習慣問題。
  3. 但是,推薦使用數值替代 lighter、bolder,因為這涉及到繼承計算的問題,用數值的話則會更為清晰明瞭。

 

本文轉載自 凹凸實驗室 ,原文連結:https://aotu.io/notes/2016/11/08/css3fontweight/