改善備用字型

Katie Hempenius
Katie Hempenius

摘要

本文將深入介紹字型備用選項,以及 size-adjustascent-overridedescent-overrideline-gap-override API。這些 API 可以使用本機字型建立與網頁字型尺寸密切或完全相符的備用字型。這樣可以減少或消除字型替換造成的版面配置位移。

如果您想略過本文,可立即使用這些 API 來開始使用:

架構工具:

  • @next/font:自 10 月 13 日起,next/font 會自動使用字型指標覆寫功能和 size-adjust 來提供相符的字型備用選項。
  • @nuxtjs/fontaine:從 Nuxt 3 開始,您可以使用 nuxt/fontaine 自動產生相符的字型,並在 Nuxt 應用程式使用的樣式表中插入。

非架構工具:

  • Fontaine:Fontaine 這個程式庫會自動產生及插入使用字型指標覆寫功能的字型備用。
  • 這個存放區包含 Google Fonts 代管所有字型的字型指標覆寫功能。您可以複製這些值並貼到樣式表中。

背景

備用字型是一種字型,可供系統尚未載入主要字型,或缺少轉譯網頁內容所需的字符時使用。舉例來說,下列 CSS 表示應使用 sans-serif 字型系列做為 "Roboto" 的字型備用。

font-family: "Roboto" , sans-serif;

備用字型可用於更快轉譯文字 (也就是使用 font-display: swap)。因此,網頁內容較早易讀且實用,但過去卻會導致版面配置的不穩定:以網頁字型替換備用字型時,經常會發生版面配置位移的情況。不過,下方討論的新 API 可讓您建立備用字型,且佔用的空間大小與網路字型不同,因此可減少或解決這項問題。

改善備用字型

產生「改善」的方法有兩種以及使用備用字型較簡單的做法只會使用字型指標覆寫 API。較複雜 (但功能更強大) 的方法會使用字型指標覆寫 API 和 size-adjust。本文將說明這兩種方法。

字型指標覆寫的運作方式

簡介

字型指標覆寫功能可讓您覆寫字型的上升、下降和行距:

  • Ascent是指字型的字符從基準線所延伸的最遠距離。
  • 平穩:測量字型字符延伸到基準線以下的最遠距離。
  • 行距也稱為「領先」可評估連續文字行之間的距離。

這張圖表顯示字型的上升、下降和線段間距。

字型指標覆寫功能可用來覆寫備用字型的上升、下降和行距,以符合網路字型的上升、下降和行距。因此,網路字型和調整過的備用字型會一律套用相同的垂直尺寸。

字型指標覆寫功能可在樣式表中使用,如下所示:

body {
    font-family: Poppins, "fallback for poppins";
}

@font-face {
    font-family: "fallback for poppins";
    src: local("Times New Roman");
    ascent-override: 105%;
    descent-override: 35%;
    line-gap-override: 10%;
}

本文開頭列出的工具可產生正確的字型指標覆寫值。不過,您也可以自行計算這些值。

計算字型指標覆寫值

以下公式可產生指定網路字型的字型指標覆寫值。字型指標覆寫的值應以百分比 (例如 105%) 寫成,而非小數。

ascent-override = ascent/unitsPerEm
descent-override = descent/unitsPerEm
line-gap-override = line-gap/unitsPerEm
敬上

舉例來說,以下是 Poppins 字型的字型指標覆寫內容:

/*
Poppins font metrics:
ascent = 1050
descent = 350
line-gap = 100
UPM: 1000
*/

ascent-override: 105%;  /* = 1050/1000 */
descent-override: 35%;  /* = 350/1000 */
line-gap-override: 10%; /* = 100/1000 */

ascentdescentline-gapunitsPerEm 的值皆來自網路字型的中繼資料。本文下一節將說明如何取得這些值。

讀取字型表格

字型的中繼資料 (尤其是字型表格) 包含計算字型指標覆寫值所需的所有資訊。

FontForge 中字型資訊對話方塊的螢幕截圖。對話方塊會顯示字型指標,例如「Typo Ascent」、「Typo Descent」和「Typo Line Gap」。
使用 FontForge 查看字型中繼資料

你可以使用以下工具讀取字型中繼資料:

  • fontkit 是專為 Node.js 打造的字型引擎,此程式碼片段說明如何使用 fontkit 計算字型指標覆寫值。
  • 「Capsize」是字型大小和版面配置程式庫。Capsize 提供的 API 可用於取得各種字型指標的相關資訊。
  • fontdrop.info 是一種網站,可讓你在瀏覽器中查看字型表和其他字型相關資訊。
  • Font Forge 是熱門的電腦版字型編輯器。如要查看 ascentdescentline-gap:請開啟 Font Info 對話方塊,然後依序選取 OS/2 選單和「Metrics」分頁標籤。如要查看 UPM:開啟 Font Info 對話方塊,然後選取 General 選單。
,瞭解如何調查及移除這項存取權。

瞭解字型表格

您可能會注意到會參照多個指標,例如有 hheaAscenttypoAscentwinAscent 指標。這是因為各種作業系統採用不同的字型轉譯方法:OSX 裝置上的程式通常會使用 hhea* 字型指標,而 Windows 裝置上的程式通常會使用 typo* (也稱為 sTypo*) 或 win* 字型指標。

系統會根據字型、瀏覽器和作業系統,使用 hheatypowin 指標顯示字型。

Mac Windows
使用「hhea」中的指標表格。 使用「typo」中的指標資料表 (表示「USE_TYPO_METRICS」)否則會使用「win」的指標表格。
Firefox 使用「typo」中的指標資料表 (表示「USE_TYPO_METRICS」)否則會使用「hhea」中的指標表格。 使用「typo」中的指標資料表 (表示「USE_TYPO_METRICS」)否則會使用「win」的指標表格。
Safari 使用「hhea」中的指標表格。 使用「typo」中的指標資料表 (表示「USE_TYPO_METRICS」)否則會使用「win」的指標表格。

如要進一步瞭解字型指標在不同作業系統中的運作方式,請參閱這篇文章,瞭解垂直指標。

跨裝置相容性

對絕大多數字型 (例如 Google Fonts 代管的字型約 90%) 中,字型指標覆寫功能無需瞭解使用者的作業系統,即使不瞭解使用者的作業系統,ascent-overridedescent-overridelinegap-override 的值也都會保持不變,無論是否套用 hheatypowin 指標都一樣。這個存放區提供適用和不適用字型的相關資訊。

如果您採用的字型需要針對 OSX 和 Windows 裝置使用個別的字型指標覆寫,請使用字型指標覆寫功能。除非您能根據使用者的作業系統變更樣式表,否則我們不建議使用 size-adjust

使用字型指標覆寫功能

由於字型指標覆寫的資料是取自網路字型中繼資料 (而非備用字型) 的測量結果,因此無論使用哪一種字型,它們都會保持不變。例如:

body {
  font-family: "Poppins", "fallback for Poppins", "another fallback for Poppins";
}

@font-face {
  font-family: "fallback for Poppins";
  src: local("Arial");
  ascent-override: 105%;
  descent-override: 35%;
  line-gap-override: 10%;
}

@font-face {
  font-family: "another fallback for Poppins";
  src: local("Roboto");
  ascent-override: 105%;
  descent-override: 35%;
  line-gap-override: 10%;
}

大小調整的運作方式

簡介

size-adjust CSS 描述元會按比例縮放字型字符的寬度和高度。例如,size-adjust: 200% 會將字型字符縮放為原始大小的兩倍。size-adjust: 50% 會將字型字符縮放為原始大小的一半。

顯示使用「size-Adjust: 50%」後結果的圖表然後「size-Adjust: 200%」

由於 size-adjust 本身並未提供改善字型備用功能的應用程式,在大多數情況下,備用字型必須縮小或縮小 (而非按比例縮放),才能符合網路字型。不過,結合 size-adjust 與字型指標覆寫值,就可以讓任兩個字型在水平和垂直方向上互相比對。

以下是在樣式表中使用 size-adjust 的方式:

@font-face {
  font-family: "fallback for poppins";
  src: local("Arial");
  size-adjust: 60.85099821%;
  ascent-override: 164.3358416%;
  descent-override: 57.51754455%;
  line-gap-override: 16.43358416%;
}

基於 size-adjust 的計算方式 (將於下一節說明),size-adjust 的值 (以及對應的字型指標覆寫) 會視使用的備用字型而定:

body {
  font-family: "Poppins", "fallback for Poppins", "another fallback for Poppins";
}

@font-face {
  font-family: poppins-fallback;
  src: local("Arial");
  size-adjust: 60.85099821%;
  ascent-override: 164.3358416%;
  descent-override: 57.51754455%;
  line-gap-override: 16.43358416%;
}

@font-face {
  font-family: poppins-fallback-android;
  src: local("Roboto");
  size-adjust: 55.5193474%:
  ascent-override: 180.1173909%;
  descent-override: 63.04108683%;
  line-gap-override: 18.01173909%;
}
敬上

計算大小調整和字型指標覆寫值

以下是計算 size-adjust 和字型指標覆寫值的方程式:

size-adjust = avgCharacterWidth of web font / avgCharacterWidth of fallback font
ascent-override = web font ascent / (web font UPM * size-adjust)
descent-override = web font descent / (web font UPM * size-adjust)
line-gap-override = web font line-gap / (web font UPM * size-adjust)

這些輸入內容 (遞增、下降和行距) 大多可以直接從網路字型的中繼資料讀取,不過,avgCharacterWidth 需要約略值。

近似平均字元寬度

一般而言,平均字元寬度只提供約略值,但在某些情況下,可以精確計算此值,例如使用單寬字型,或是已事先得知文字字串內容時。

計算 avgCharacterWidth 的基本方法之一,就是取得所有 [a-z\s] 字元的平均寬度。

 比較個別 Roboto [a-zs] 字符的寬度的圖表。
Roboto 字符寬度

不過,若設定所有字元的權重相等,可能會導致常用字母 (例如 e) 的寬度變小,不常使用的字母 (例如 z) 的寬度則過重。

想要提升準確度,還有一種更複雜的做法是將「字母頻率」納入考量,改為計算「頻率加權平均寬度」([a-z\s] 個字元)。這篇文章很適合參考英文文字的字母頻率和平均字詞長度。

顯示英文字母頻率的圖表。
字母頻率 (英文)

選擇方法

本文所討論的兩種方法各有優缺點:

  • 如果您剛開始對字型備用項目進行最佳化時,自行使用字型指標覆寫功能是不錯的方法。雖然這是一種更簡單的方法,但通常功能可以顯著降低與字型相關的版面配置位移幅度。

  • 另一方面,如果您想提高精確度,且願意執行一些工作和測試,加入 size-adjust 是不錯的做法。在正確實作的情況下,此方法可有效消除與字型相關的版面配置位移。

,瞭解如何調查及移除這項存取權。

選擇備用字型

本文所述的技巧是使用字型指標覆寫和 size-adjust 來轉換廣泛提供的本機字型,而不是嘗試尋找近似於網路字型的本機字型。選擇本機字型時,請務必記住,少數字型普遍使用本機字型,而且所有裝置都沒有單一字型。

建議使用 Arial 做為 Sans Serif 字型的備用字型,而 Times New Roman 則是 Serif 字型的建議備用字型。不過,這些字型不適用於 Android (Android 上只有 Roboto 的系統字型)。

以下範例使用三種備用字型來確保裝置廣泛的覆蓋範圍:指定 Windows/Mac 裝置的備用字型、指定 Android 裝置的備用字型,以及使用一般字型系列的備用字型。

body {
  font-family: "Poppins", poppins-fallback, poppins-fallback-android, sans-serif;
}

/*
Poppins font metrics:
- ascent = 1050
- descent = 350
- line-gap = 100
- UPM: 1000
AvgCharWidth:
- Poppins: 538.0103768
- Arial: 884.1438804
- Roboto: 969.0502537
*/

@font-face {
  font-family: poppins-fallback;
  src: local("Arial");
  size-adjust: 60.85099821%;
  ascent-override: 164.3358416%;
  descent-override: 57.51754455%;
  line-gap-override: 16.43358416%;
}

@font-face {
  font-family: poppins-fallback-android;
  src: local("Roboto");
  size-adjust: 55.5193474%:
  ascent-override: 180.1173909%;
  descent-override: 63.04108683%;
  line-gap-override: 18.01173909%;
}
敬上

要求提供意見

如果您對於使用字型指標覆寫功能和「size-adjust」的體驗有任何意見,請與我們聯絡。