網頁字體 Webfont 指南:中文字型選擇與載入優化
網頁字體能讓文字跨裝置一致顯示,但設定不當會拖慢 LCP。本指南從中文字型選擇到 WOFF2、font-display swap 與子集化,帶你兼顧排版質感與 Core Web Vitals。
作者:褚崇名(Sliven)
本頁目錄
- Webfont 是什麼:和系統字到底差在哪
- 字型檔格式:WOFF2 為什麼是中文字型的必選
- 中文字型為什麼是效能殺手
- CJK Unicode 區塊:子集化必備的技術地圖
- 中文字型怎麼選:黑體、明體、圓體的實戰判斷
- font-display 五種策略,哪一種最適合你
- FontFace API:用 JavaScript 精準控制字型載入時機
- 把字型檔變小:子集化與 unicode-range
- 字型效能預算:如何設定可驗證的資源上限
- 預載入、preconnect 與 CDN:從傳輸層加速
- 用 preload 提前下載關鍵字型
- 用 preconnect 提早建立連線
- CDN 是字型加速的基本盤
- 可變字體 Variable Fonts:一個檔案搞定所有字重
- FOUT、FOIT 與 CLS:字體載入的三大體驗瑕疵
- 無障礙考量:字型不只是為了好讀
- 現代 CSS 字型屬性:OpenType 特性在中文的應用
- 免費與付費字型資源怎麼挑
- WordPress 站長的 webfont 實戰
- 進階技巧:讓字體和快取、延遲載入聯手
- 常見的地雷與迷思
- 字型策略決策矩陣:什麼情況用什麼做法
- 怎麼診斷字體效能問題:DevTools 實戰
- 字體優化行動清單:七步把字型效能拉起來
重點摘述
- 網頁字體(webfont)是透過
@font-face把字型檔下載到瀏覽器再渲染的技術,它讓你脫離系統預設字、做出真正的品牌質感。 - 中文字型要涵蓋的字形通常比拉丁字型多,完整字型檔可能明顯較大;實際大小會受字形範圍、格式、字重與子集化方式影響。
- 想同時顧質感與速度,主要方向是:選對字、做子集化(subsetting)、用對
font-display與載入策略。
設計師交出一版美到不行的視覺稿,字體優雅、字距精準,客戶一看就買單。結果網站上線,手機打開來,畫面空白了一段時間才蹦出文字,接著字型又「啪」地閃一下換成正式字體。訪客心裡只剩一個念頭:這網站是不是壞了。
字體是網站效能優化時常被低估的變數之一。它不像圖片那樣顯眼,卻可能延後最大內容繪製(Largest Contentful Paint, LCP),或在替換字型時造成版面位移(Cumulative Layout Shift, CLS)。目前的 Core Web Vitals 是 LCP、互動至下一次繪製(Interaction to Next Paint, INP)與 CLS;INP 已在 2024 年 3 月取代 FID,指標組合的演進見 web.dev 的 Core Web Vitals 說明。
這篇會把網頁字體從底層運作、中文字型的特殊難題、載入優化到資源挑選一次講清楚。不管你是自己架站的創業者、接案設計師,還是顧 SEO 的行銷人,看完都能動手把字體效能拉起來。如果你之前完全沒碰過 CSS,可以先把CSS 入門全攻略看過一遍,回來會更順。
先給一個觀念定位,這篇不是教你「怎麼把字型弄漂亮」,漂亮是設計師的事。這裡要談的是在質感和速度之間找到平衡點的工程判斷。每一個掛上去的 webfont 都是一筆效能負債,你的任務是讓這筆負債付出最小代價、換回最大價值。很多團隊之所以字體出問題,不是不懂技術,而是從來沒把字體當成效能變數來管理。設計師只管好不好看、工程師只管能不能跑、行銷只管排不排得上,沒有人對「字體下載成本」負責。結果就是一個頁面默默掛了多套完整字型,LCP 悲劇卻沒人發現。希望你看完這篇,能成為團隊裡那個把字體帳算清楚的人。
Webfont 是什麼:和系統字到底差在哪
所謂的 webfont,不是某一種字型品牌,而是一種把字型檔當成網頁資源下載的技術。用 CSS 的 @font-face 宣告字型名稱、檔案位置、格式,瀏覽器遇到用到這個字型的文字時,就會去把檔案抓下來渲染。
在 webfont 出現之前,網頁只能用「訪客電腦裡有裝」的系統字。所以早期中文網站清一色是新細明體或標楷體,因為這兩套幾乎每台 Windows 都有。問題是,新細明體在螢幕上的閱讀體驗真的很差,而設計師精心挑的思源黑體、蘋方,只要訪客電腦沒裝,就完全顯示不出來。
webfont 解決的就是這件事:只要瀏覽器支援而且字型檔成功載入,網站就能減少不同系統預設字型造成的差異。仍要準備合適的 fallback,因為網路、瀏覽器設定或字型服務異常時,正式字型不一定能載入。Google Fonts 是常見的免費開源字型庫之一。
但代價很明確:要下載字型檔。下載就要時間、要頻寬,也會和其他關鍵資源競爭下載優先順序。中文字型通常涵蓋更多字形,因此這個代價往往比拉丁字型明顯。接下來這段就是關鍵。
字型檔格式:WOFF2 為什麼是中文字型的必選
談到 webfont,很多人只知道「要一個檔案」,但檔案格式本身會直接影響壓縮率和下載速度。市面上有四種常見格式,每一種的壓縮技術和瀏覽器支援度都不同。
| 格式 | 壓縮技術 | 壓縮率(相較於 TTF) | 瀏覽器支援版本 | 中文字型適用性 |
|---|---|---|---|---|
| TTF(TrueType) | 無壓縮 | 基準(1.0x) | 所有現代瀏覽器 | 檔案太大,不推薦 |
| EOT(Embedded OpenType) | 無(或選用性壓縮) | 接近 TTF | 僅 IE 系列(見 Wikipedia 的 Embedded OpenType) | 已淘汰,不需考慮 |
| WOFF(Web Open Font Format) | zlib 壓縮 | 依字型內容而異 | IE 9+、所有現代瀏覽器 | 可用但不最優 |
| WOFF2(Web Open Font Format 2.0) | Brotli 壓縮 | 通常比 WOFF 更小;web.dev 的資料指出壓縮效果最高可再改善約 30% | Chrome 36+、Firefox 35+、Safari 10+、Edge 14+(Can I Use) | 中文字型強烈推薦 |
這張表為什麼特別把 WOFF2 標出來?因為它使用 Brotli 壓縮,通常能比 WOFF 進一步縮小檔案。實際節省幅度取決於字型的輪廓、字形數量、hinting、可變軸與子集化方式,不能直接用固定比例推算 LCP。
瀏覽器支援度方面,WOFF2 在 2026 年已經幾乎全面覆蓋(全球使用率 97% 以上,依 Can I Use 的統計)。微軟是在 2022 年 6 月 15 日終止特定 Windows 10 版本上的 IE 11 桌面應用程式支援,不是所有 IE 元件在同一天全面終止;Edge 的 IE 模式至少支援到 2029 年。不過面向現代公開網站時,通常不需要為 IE 提供 webfont 降級檔,Microsoft 在IE 11 支援終止公告中有完整說明。如果你的專案明確需要照顧舊版瀏覽器,可以在 @font-face 裡同時宣告 WOFF2 和 WOFF,讓瀏覽器自行選擇:
@font-face {
font-family: 'Noto Sans TC';
src: url('/fonts/noto-sans-tc.woff2') format('woff2'),
url('/fonts/noto-sans-tc.woff') format('woff');
font-weight: 400;
font-display: swap;
}
但實際上,對中文字型來說,WOFF2 幾乎是唯一值得推薦的格式。其他格式只會在檔案大小和 HTTP 請求數上製造多餘成本,不具實戰價值。
中文字型為什麼是效能殺手
只涵蓋基本拉丁字母、數字和常用符號的子集,需要的字形相對少。中文呢?《常用國字標準字體表》收了 4808 字,若再涵蓋次常用字、異體字與標點符號,字形數量會顯著增加。每個字元都需要對應的字形資料,檔案通常也會隨之變大。
完整繁體中文字型即使轉成 WOFF2,仍可能比拉丁字型子集大很多。叫訪客的手機下載一整套字型,只為了把少量標題字從系統字換成品牌字,往往不划算;實際檔案大小應直接檢查所選字型與字重。
而且中文的問題還不只檔案大。內容持續更新的網站不一定能預先知道每一頁會用到哪些字,固定子集太小可能頻繁 fallback,直接載完整字集又可能傳送大量頁面沒用到的字形資料。
老實說,這就是中文網站做 webfont 最核心的矛盾:你要質感,就得付出下載成本;你要速度,就得忍受系統字。好消息是,這個矛盾不是不能解,後面會講到子集化和 unicode-range 怎麼降低成本。在動手優化之前,先把「字型選擇」這件事講清楚,因為選錯字,後面優化做得再徹底也救不回來。
CJK Unicode 區塊:子集化必備的技術地圖
要精準地把中文字型子集化,需要了解 CJK(中日韓)字元在 Unicode 裡的分布。Unicode 把中文字元分散在好幾個區塊,每一個區塊對應一個編碼範圍。知道這些範圍,就能告訴字型工具「只裁出這些區塊」,而不是盲目地抓全部字元。
繁體中文最常遇到的幾個關鍵區塊:
| Unicode 區塊名稱 | 編碼範圍(十六進位) | 字元數量 | 常見內容 | 子集化建議 |
|---|---|---|---|---|
| CJK Unified Ideographs(統一漢字) | U+4E00 - U+9FFF | 20,992 個碼位 | 常用與次常用漢字主體 | 中文站必選 |
| CJK Unified Ideographs Extension A(擴展 A) | U+3400 - U+4DBF | 6,592 個碼位 | 生僻字、古文、人名 | 依內容選擇 |
| CJK Compatibility Ideographs(相容漢字) | U+F900 - U+FAFF | 512 個碼位(已指派 472 字) | 舊版編碼相容字 | 通常可省略 |
| Halfwidth and Fullwidth Forms(半形全形) | U+FF00 - U+FFEF | 240 個碼位(已指派 225 字) | 全形標點、全形英數 | 中文站建議保留 |
| CJK Symbols and Punctuation(CJK 符號標點) | U+3000 - U+303F | 64 個碼位 | 書名號、頓號、句讀 | 中文站必選 |
這張表實際怎麼用?假設你的站是科技內容,除了 CJK Unified Ideographs(U+4E00 到 U+9FFF)、Halfwidth and Fullwidth Forms(U+FF00 到 U+FFEF)與 CJK Symbols and Punctuation(U+3000 到 U+303F),也要依實際內容保留基本拉丁字母、一般標點、注音或其他用到的區塊。先把字型實際切成對應的子集檔,再在 @font-face 裡用 unicode-range 描述各檔涵蓋的字元,瀏覽器才會依頁面文字下載需要的檔案;unicode-range 本身不會裁小字型檔。
另一個實戰技巧是「頻率分析子集化」。用工具掃描網站所有文章內容,統計每個字的出現頻率,然後只把最常見的那幾千字做成子集。以一個文字密集的內容站為例,統計後往往會發現少數幾千個字就涵蓋了頁面絕大部分的文字,這時針對這組常用字做一個專門的子集檔,體積會遠小於完整字型。實際數字因站而異,建議自己跑一次掃描再決定子集範圍。
這種頻率分析可以自己寫腳本做;Google Fonts 的一般機制則是把字型預先切成多個 unicode-range 子集檔,再由瀏覽器依頁面實際出現的文字決定下載哪些檔案。這不是逐頁即時產生字型;若是文字內容固定的標題或 Logo,可用 Google Fonts CSS API 的 text= 參數要求只含指定字元的檔案。若需要掌控裁切邊界,則可自行做靜態子集化。
中文字型怎麼選:黑體、明體、圓體的實戰判斷
挑中文字型,第一個要決定的不是「哪一款好看」,而是這個字型要用在什麼場景。不同用途,判斷標準完全不一樣。下面這張表把常見的中文字體分類整理出來,可以對著自己的需求挑:
| 字體類型 | 視覺特徵 | 適合場景 | 不適合場景 |
|---|---|---|---|
| 黑體(Sans-serif) | 筆畫粗細一致、沒有襯線,螢幕顯示銳利 | 網頁正文、UI 介面、行動裝置、大量文字 | 需要古典、人文氣質的內容 |
| 明體(Serif) | 有襯線、橫細豎粗,印刷感強 | 長文閱讀、文學內容、法律金融、正式文件 | 小字螢幕顯示(易糊) |
| 圓體 | 筆畫尾端圓潤,親和力高 | 親子、餐飲、生活風格、女性品牌 | B2B、科技、金融專業形象 |
| 手寫體/美工體 | 個性強烈、辨識度高 | 標題、裝飾字、Banner(少量使用) | 正文(閱讀疲勞) |
一個常用的判斷原則:正文優先考慮螢幕閱讀性,標題看品牌,裝飾字少量使用。黑體常被用於螢幕正文,但明體是否清楚仍取決於字型設計、字級、顯示器與渲染環境,沒有適用所有網站的固定字級門檻。標題字級較大時較能保留筆畫細節,這時候用明體也能創造質感和權威感,很適合金融、法律、教育類的網站。
如果想看更具體的字體推薦,可以參考完整的中文字體設計指南,裡面有必藏字體的詳細評比,涵蓋思源黑體、思源宋體、方正系列等。英文搭配的字型挑選,則可以參考英文字體推薦這篇,襯線、非襯線到手寫體都收齊了。
特別提一個新手常踩的坑:很多人以為「字型越多越豐富」,一個頁面同時掛黑體、明體、圓體、手寫體多套字型。先不講視覺混亂,額外下載也可能拖慢 LCP。建議盡量限制字型家族數量,例如一套正文、一套標題或裝飾;能用一套搭配字重變化去創造層次更好。這個觀念在做排版設計時特別重要。
font-display 五種策略,哪一種最適合你
選好字、掛上去之後,第一個要處理的技術問題就是 font-display。這個 CSS 屬性決定了瀏覽器在字型檔還沒下載完之前,要怎麼處理文字顯示。換句話說,它就是在「讓訪客看見文字」和「堅持顯示正確字型」之間做取捨(見 MDN 的 font-display 文件,2026)。
它有五個值,這裡直接給實戰判斷,不要背規格:
| 值 | 行為 | 適合場景 |
|---|---|---|
auto |
交給瀏覽器採用預設策略,實際行為由 user agent 決定 | 不要用,行為不可控 |
block |
有一段短阻擋期,之後顯示備用字;字型載入後仍可替換(見 Chrome Developers 的說明) | 品牌字、Logo(短時間隱藏可接受) |
swap |
幾乎不隱藏文字,立刻顯示備用字,字型下載完瞬間替換 | 正文、標題(最推薦) |
fallback |
極短時間隱藏,隨後顯示備用字,下載若太慢就放棄替換 | 折衷選擇,兼顧兩端 |
optional |
只給極短的網路時間下載,抓不到就永遠用系統字 | 純裝飾字,效能優先於一致 |
若正文優先避免文字隱藏,swap 是常見起點,因為瀏覽器會先用備用字顯示內容。載入速度可能影響使用體驗與離開機率,但不同網站的幅度不會相同(見 web.dev 的〈Why does speed matter?〉)。swap 的代價是 FOUT(Flash of Unstyled Text,無樣式文字閃爍),字型替換時可能閃動或造成位移,後面會再處理。
什麼時候用 block?只有當字型是品牌辨識核心、文字量很少,而且測試後確定短暫隱藏可接受時,才值得考慮。例如 Hero 區的少量品牌標準字。不要把整頁正文都設成 block,否則字型載入期間可能出現 FOIT,行動裝置上尤其痛苦。
optional 是一個很特別的值,它只有極短的阻擋期且沒有交換期;如果字型未及時可用,這次頁面檢視就會繼續使用備用字。對純裝飾用的手寫體或特殊字型來說可能很合理,因為沒有也不影響閱讀。
FontFace API:用 JavaScript 精準控制字型載入時機
前面提到的 font-display 是一個「設定後就不管」的 CSS 屬性,但如果需要更精準的控制,比如想要在字型載入過程中顯示載入狀態、或者想要根據網路狀況動態決定要不要載入某個字型,那就需要用 JavaScript 的 FontFace API。
FontFace API 屬於 CSS Font Loading Module,能讓你用程式碼創建、載入、監聽字型。語法像這樣:
const font = new FontFace('Noto Sans TC', 'url(/fonts/noto-sans-tc.woff2) format("woff2")', {
display: 'swap'
});
font.load().then(() => {
document.fonts.add(font);
console.log('字型載入完成');
}).catch((error) => {
console.error('字型載入失敗', error);
});
這段程式碼會創建一個 FontFace 物件,然後載入它。載入成功後,把字型加到 document.fonts 集合,網頁就能使用這個字型。而且因為這是非同步的,你可以在 .then() 裡做任何你想要的後續處理,比如更新 UI 狀態、發送分析事件、或者觸發其他動畫。
FontFace API 的實戰用途主要有三個:
- 條件式載入:根據螢幕尺寸或網路狀況決定要不要載入某些字型。例如,在行動裝置上跳過裝飾用字型,只載正文黑體。
- 載入狀態反饋:在字型載入過程中顯示「載入中」的視覺提示,讓訪客知道不是網站掛了。
- 字型載入優先順序:先載 LCP 元素用的字型,等那個字型載完再載次要的字型,避免資源搶頻寬。
瀏覽器支援度方面,FontFace API 自 2020 年 1 月起已在所有主流瀏覽器可用,是 Baseline 標準功能(見 MDN 的 FontFace 條目)。IE 系列不支援,但前面說過,IE 已經不具實戰考量。如果需要支援舊版瀏覽器,可以用 @font-face 當降級策略。
如果字型已透過 @font-face 宣告,不需要再建立一個指向相同資源的新 FontFace 物件;可改用 document.fonts.load()、document.fonts.check() 或 document.fonts.ready 操作既有字型。CSS 與 Font Loading API 可以搭配使用;是否產生額外網路請求還會受 URL、快取與瀏覽器實作影響,不能一概說一定下載兩次。
把字型檔變小:子集化與 unicode-range
前面提過,中文字型最大的痛點是「檔案大、但實際用到的字很少」。子集化(subsetting)就是直接解決這件事的技術:把字型檔裡用不到的字元全部砍掉,只留下你真正需要的。
完整中文字型通常會包含大量單一頁面用不到的字形;只保留實際需要的常用國字與英數符號後,檔案可明顯縮小。實際壓縮結果取決於字型本身的設計、保留字元、字重與工具參數,不能用固定容量或比例概括,建議用 pyftsubset 之類的工具實測。
子集化有兩種做法,要分清楚:
- 靜態子集:在網站建置階段,用工具(例如 pyftsubset、fonttools)把字型檔預先裁切成固定字集。適合內容變動不大的形象網站、登入頁。優點是快、穩定,缺點是字集固定,碰到頁面出現子集外的字就會 fallback 到系統字。
- 分片子集:預先把字型切成多個檔案,以
unicode-range描述範圍,再由瀏覽器依頁面文字下載需要的分片;Google Fonts 的一般 CSS 回應採用這類機制。它不同於伺服器依每一頁內容即時重建字型;真正的動態子集需要服務端支援,內容變動時也要正確更新。
和子集化搭配的還有 unicode-range。這個 CSS 屬性告訴瀏覽器「這個字型檔涵蓋哪些 Unicode 範圍」。瀏覽器會先掃描頁面文字,只有當頁面真的用到 unicode-range 宣告的字元時,才會下載那個字型檔。可以把字型拆成多個檔,每個檔對應一段 Unicode 範圍,這樣英文頁就只載英文字型檔、中文頁才載中文字型檔,互不干擾。
這個手法在多語系網站特別有用。假設你同時經營中英文版,與其一次載一包包含所有語系的超大字型,不如拆開來,讓英文訪客只下載需要的拉丁字型子集、中文訪客才下載子集化過的中文檔。對響應式設計的多語系站來說,這是值得優先評估的做法。
字型效能預算:如何設定可驗證的資源上限
談到字型優化,很多網站只是「能小就小」,沒有設定明確的效能目標。即使字型檔縮小,LCP 仍可能受伺服器回應、資源發現時間、網路狀況與 LCP 元素類型影響,因此不能只看檔案大小判斷成效。
要真正把字型優化做到位,可以設定「字型效能預算」,限制每頁使用的字型家族、字重、請求數與傳輸量,再以實測 LCP 驗證。LCP 的官方「良好」門檻是在第 75 百分位數達到 2.5 秒以內(依 web.dev 的 LCP 文件);但無法從這個門檻直接換算出通用的字型 KB 上限或「佔 LCP 比例」。下面是一個不綁死數字的預算框架:
| 網站類型 | 效能優先序 | 字型預算原則 | 驗證方式 | 適用情境 |
|---|---|---|---|---|
| 形象站、登入頁 | 高 | 限制家族與字重,只預載首屏實際使用的字型 | 在目標裝置與網路條件量測 LCP | 視覺重質感、內容少 |
| 內容型網站 | 高 | 正文優先,中文採子集或分片載入 | 比較字型傳輸量、LCP 與 CLS | 文章站、部落格 |
| 電商、SaaS | 最高 | 系統字優先,只保留有明確價值的 webfont | 以真實使用者資料與轉換流程驗證 | 轉換導向、功能多 |
這張表是規劃方法,不是官方標準。實際上限要根據自家訪客裝置、網路條件、快取命中率與 LCP 元素實測。假設內容型網站同時載入正文黑體和標題明體,就應比較保留兩套字型的體驗價值,以及刪減字重、子集化或改用系統字後的 LCP 與 CLS 差異。
設定預算的好處是讓優化有明確的成功標準。不是抽象地「盡量小」,而是先在代表性的測試環境量出基準,再訂出專案自己的傳輸量與 LCP 上限。當設計師想用某套商業字型時,團隊就能用實際檔案與測試結果決定要刪減字重、子集化或換字型。
預算也不是一成不變。如果你的站主要訪客都在台灣都市區的有線網路,網路速度不是瓶頸,字型預算可以稍微放寬。如果你的站目標客群在新興市場、或者行動訪客比例很高,預算就要更嚴格。記得定期用 Lighthouse 或 PageSpeed Insights 驗證實際的 LCP 值,調整預算。
預載入、preconnect 與 CDN:從傳輸層加速
子集化把檔案變小了,接下來要想的是「怎麼讓這個變小的檔案更快送到訪客手上」。這裡有兩個層面:下載時機和下載路徑。
用 preload 提前下載關鍵字型
預設情況下,瀏覽器要等解析 CSS、發現某段文字用了某個 webfont,才會開始下載字型檔。這個「發現」的過程會發生在頁面渲染的中後段,等於字型下載被往後延遲了。<link rel="preload"> 的作用,就是告訴瀏覽器「這個字型很重要,一開始就先抓」,讓字型下載提前到和 HTML、CSS 解析同時進行(見 web.dev 的 preload 字型說明)。
寫法像這樣:
<link rel="preload" href="/fonts/noto.woff2" as="font" type="font/woff2" crossorigin>
由於字型在瀏覽器規範裡預設就是以 CORS 模式請求,preload 的 crossorigin 設定必須和實際請求一致(通常用 crossorigin="anonymous"),否則瀏覽器會重複下載同一個檔案(見 MDN 對 rel="preload" 的說明)。遇到 preload 沒有效果時,可以先從開發者工具確認這一點。
用 preconnect 提早建立連線
如果你的字型放在第三方網域(例如 fonts.googleapis.com),瀏覽器可能要先做 DNS 查詢、TCP 交握與 TLS 協商。用 preconnect 可以讓瀏覽器在還沒實際要下載字型前,就先建立連線(見 web.dev 的 resource hints 說明):
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
Google Fonts 的 CSS 由 fonts.googleapis.com 提供,字型檔通常由 fonts.gstatic.com 提供,因此若確定首屏會使用,對這兩個來源設定正確的 preconnect 可減少連線建立等待。
CDN 是字型加速的基本盤
如果訪客分布跨多個地區,可以評估透過 CDN(內容傳遞網路)提供字型檔。CDN 可從邊緣節點提供快取資源,減少部分訪客回源的網路距離;實際改善幅度取決於 CDN、快取命中、主機位置與訪客網路。CDN 的原理和挑選,可以參考CDN 網站加速專文,這裡不重複展開。
可變字體 Variable Fonts:一個檔案搞定所有字重
近幾年最值得關注的字體技術,是可變字體(Variable Fonts)。傳統字型一個字重就是一個獨立檔案,常規、粗體、中等各一個檔,掛五個字重就是五次下載。可變字體把這些字重全部收進同一個檔案,用一個叫 axis(軸)的參數來控制粗細變化,瀏覽器只要下載一次,就能透過 CSS 即時調出任何字重。
對中文 webfont 來說,可變字體特別值得比較。靜態字體通常要為每個字重載入不同檔案,可變字體則能用一個檔案涵蓋一段字重範圍;它有機會降低總下載量,但效果取決於實際檔案、使用字重與子集化結果,不能套用固定比例。
實際用法也不複雜。CSS 裡用 font-variation-settings 指定軸的數值,例如思源黑體(Source Han Sans)的可變字體版本,"wght" 400 是常規、"wght" 700 是粗體,中間的 500、600 也能平滑調出來(見 Adobe 的 Source Han Sans 專案)。甚至能在 hover 或捲動時動態改變字重,做出傳統字型做不到的互動效果。
當然可變字體不是沒有代價。它的單一檔案通常比單一字重的靜態檔大,如果網站只用一個字重,硬上可變字體反而可能不划算。沒有固定的「三個字重」門檻,應把實際會載入的靜態檔總量,和子集化後的可變字體檔案直接比較。Noto Sans TC(重量軸 100 到 900)和 Noto Serif TC(重量軸 200 到 900)都已在 Google Fonts 上以可變字體形式提供,想嘗試可以直接從這兩套入門。選用之前,記得確認目標瀏覽器支援度;若仍要照顧舊版環境,就準備靜態字型檔當退路。
FOUT、FOIT 與 CLS:字體載入的三大體驗瑕疵
字型載入過程中會出現三種讓訪客不舒服的視覺瑕疵,一定要知道名字和成因,才有辦法對症下藥。
FOIT(Flash of Invisible Text,不可見文字閃爍):在字型交換期之前,瀏覽器可能暫時隱藏使用該字型的文字。font-display: block 會保留一段短阻擋期;實際時間由瀏覽器決定。弱網環境下,過長的空白文字會明顯傷害閱讀體驗。
FOUT(Flash of Unstyled Text,無樣式文字閃爍):瀏覽器先用系統備用字顯示文字,等字型下載完再替換。這正是 font-display: swap 的行為。替換的瞬間,字寬、字高、行距可能都會變動,畫面會「跳」一下;對文字型 LCP 元素而言,字型顯示策略也可能影響 LCP 時序,不能把 FOUT 視為與 LCP 完全無關。
CLS(Cumulative Layout Shift,累計布局位移):當系統備用字和正式 webfont 的字寬、字高不同,替換的瞬間整段文字的寬度會改變,連帶把後面的元素推位。讀者正在看文章,突然整個版面跳一下,這就是 CLS。它是 Core Web Vitals 的三大指標之一,Google 在評估頁面體驗時會直接看這個數字(見 2020 年 5 月 Google Search Central Blog 的說明)。
怎麼把 CLS 壓下來?核心原則是讓備用字和正式字的尺寸越接近越好。實務上有幾個做法:
- 挑尺寸接近的備用字:例如你的 webfont 是黑體,備用字就指定目標平台可用的系統黑體(如 PingFang TC、Microsoft JhengHei),不要在未測試下 fallback 到尺寸差異很大的字型。
- 用 font-size-adjust:這個 CSS 屬性利用 x-height(小寫字母高度)與字級的比值,讓備用字在視覺上更接近正式字的尺寸,縮小兩者落差,細節見 MDN 的 font-size-adjust 文件。
- 預留文字容器的高度:標題區、Hero 區在字型還沒載入前,先用 min-height 或 aspect-ratio 撐出空間,避免字型下載完才把版面撐開。
這幾個手法聯合起來,可以把字型替換造成的位移降到訪客幾乎感覺不到的程度。想更深入了解 Core Web Vitals 整體怎麼優化,可以看Core Web Vitals SEO這篇的完整拆解。
無障礙考量:字型不只是為了好讀
談到字型,多數人只想到「好不好看」或「好不好讀」,但從無障礙設計(a11y)的角度,字型選擇會直接影響某些訪客能不能順利使用你的網站。
目前的 W3C Recommendation 是 WCAG 2.2(Web Content Accessibility Guidelines);其中有幾條與文字呈現直接相關的準則:
- Success Criterion 1.4.4 Resize Text:文字必須能在不使用輔助技術的情況下放大到 200% 而不流失內容或功能。這意味著佈局不能假設固定字寬,要用相對單位和響應式設計。
- Success Criterion 1.4.12 Text Spacing:使用者必須能在不改變內容的前提下,調整行高、段落距、字元距、字距,細節見 W3C WAI 的 Understanding SC 1.4.12。
- Success Criterion 1.4.3 Contrast (Minimum):文字與背景的對比度,AA 等級至少要 4.5:1(大型文字 3:1),AAA 等級至少要 7:1(大型文字 4.5:1),細節見 W3C WAI 的 Understanding SC 1.4.3。
SC 1.4.12 的重點不是要求網站預設採用固定間距,而是當使用者把行高、段落後距、字母距與字距覆寫到指定測試值時,不得流失內容或功能。測試值如下:
| 檢查項目 | SC 1.4.12 測試覆寫值 | 驗證重點 |
|---|---|---|
| 行高 | 至少 1.5 倍字級 | 覆寫後文字不得被裁切或重疊 |
| 段落間距 | 至少 2 倍字級 | 覆寫後段落與容器不得遮住內容 |
| 字母間距 | 至少 0.12 倍字級 | 覆寫後字元與控制項仍須完整可用 |
| 字距 | 至少 0.16 倍字級 | 覆寫後文字可換行且不遺失 |
WCAG 本身沒有規定正文字級的最小值。實作上應確保使用者把文字放大到 200% 時,內容與功能仍然完整;相對單位通常較容易做出可伸縮版面,但使用 px 本身不會自動構成違規,真正的問題是放大後出現裁切、重疊或功能流失。
除了這些基本要求,還有針對特殊需求的考慮:
- 閱讀障礙:沒有一套字型能保證適合所有 dyslexia(失讀症)讀者。應優先確保字形容易區辨、間距可調、行長合理,並讓使用者能覆寫字型;若這是核心受眾,應以實際使用者測試判斷。
- 螢幕閱讀器:螢幕閱讀器主要依 DOM、文字內容與無障礙樹朗讀,不會因字型外觀「設計化」就改變底層文字。不過低辨識度字形仍會傷害使用螢幕放大或以視覺閱讀的使用者,因此不可過度犧牲可讀性,也不要用圖示字型取代有語意的標籤。
- 色彩對比:雖然這不是字型本身的問題,但字型和背景的對比度必須符合 WCAG AA 等級(正常文字至少 4.5:1)或 AAA 等級(正常文字至少 7:1)。很多時候,不是字型不好讀,是對比度不夠。
如果需要驗證網站是否符合 WCAG,可以用 axe DevTools 或 WAVE 這類無障礙檢測工具協助找出部分問題,更多工具可查 W3C WAI 的檢測工具清單。自動檢測無法涵蓋所有準則;文字縮放、spacing 覆寫、閱讀順序與實際可用性仍需要人工測試。
現代 CSS 字型屬性:OpenType 特性在中文的應用
多數人用 CSS 字型屬性只知道 font-family、font-size、font-weight,但現代 CSS 還有許多能啟用字型內建功能的屬性,這些功能來自 OpenType 規範(見 MDN 的 OpenType 指南)。
font-variant-numeric 是其中實用的一個。它能控制數字的顯示方式,比如:
.stats {
font-variant-numeric: tabular-nums;
}
這段 CSS 會讓數字以「等寬」方式顯示,每個數字佔一樣寬度,對應 OpenType 的 tnum feature。這對顯示表格、圖表、價格特別有用,因為數字不會因為位數不同而跳動(見 MDN 的 font-variant-numeric 文件)。
另一個常用的是 font-feature-settings,它能直接操作 OpenType 的 feature tag。比如說,某些字型提供「連字」(ligatures)功能,讓特定字元組合顯示成特殊設計:
font-feature-settings: "liga" 1;
這會啟用標準連字。如果想同時啟用標準連字與自由連字:
font-feature-settings: "liga" 1, "dlig" 1;
dlig 是 discretionary ligatures(自由連字),是設計師額外設計、預設關閉的連字組合。
在中文網站,OpenType 特性的實用性相對有限,因為多數中文字型沒有像歐文字型那麼豐富的 feature tag。但如果你同時使用英文字型(比如英文標題、英文引言),font-feature-settings 就能發揮作用。英文字型常見的 feature tag 還有:
smcp:小型大寫字母(small caps)c2sc:小型大寫字母(從大寫轉成)onum:舊式數字(oldstyle figures)tnum:表格數字(tabular figures)
如果你的網站有很多數據視覺化、表格或報表內容,而且所選字型支援,tnum 會很實用。
要注意的是,font-feature-settings 是一個「低階」屬性,它直接操作 OpenType tag,語法不直觀。如果 CSS 提供了專用屬性(像 font-variant-numeric),優先用專用屬性,只有在需要特殊功能時才用 font-feature-settings。
免費與付費字型資源怎麼挑
市面上字型資源很多,這裡把最值得用的整理出來,幫你省下比較的時間。
| 資源 | 類型 | 優點 | 缺點 |
|---|---|---|---|
| Google Fonts | 免費 | 開源、支援 unicode-range 子集、CDN 免設定 | 中文字型選擇少,載入要連 Google 伺服器 |
| Adobe Fonts | 付費(含 Creative Cloud) | 字型庫龐大、商業授權清楚、品質穩定 | 需依授權使用 Adobe 嵌入碼;東亞字型的動態子集會使用 JavaScript |
| Noto Serif TC | 免費(Google 贊助) | 繁體中文支援完整、開源、與 Noto Sans TC 配對 | 完整檔案大,要自己子集化 |
| 思源黑體/宋體 | 免費(開源) | 業界標準、多字重、社群維護成熟 | 要自行處理託管與子集化 |
| 系統字(PingFang TC、Microsoft JhengHei) | 免費 | 零下載、零延遲 | 無法跨平台一致、無品牌個性 |
Google Fonts 是常見起點。它提供 CDN、子集機制與 HTTPS,只要貼一段 <link> 就能用。繁體中文字型可利用網站的語言與書寫系統篩選器查看現有選擇,其中 Noto Sans TC 和 Noto Serif TC 是常見的開源字型。
Adobe Fonts(前身 Typekit)是另一個主流選擇。付費 Creative Cloud 方案包含 Adobe Fonts,授權涵蓋個人與商業用途。網站使用 Adobe 提供的 web project 嵌入程式碼與託管服務,不能直接把字型檔下載後自行託管;自 2018 年起,Creative Cloud 訂閱所託管的 webfont 已沒有每月頁面瀏覽量上限(依 Adobe 於 2022 年的方案上限說明與 2024 年的網站字型嵌入指南)。
如果你的品牌需要獨特的字型(非開源、非 Google/Adobe 提供),就要向字型廠商確認並購買適用的商業授權。成本與品牌獨特性因字型和方案而異;買之前一定要確認條款是否允許 webfont 嵌入、自行託管,以及授權範圍與計費方式。
一個常被放過的免費資源是系統字。如果只追求「乾淨、好讀、快速」,不強求品牌專屬字型,可以使用 macOS 的 PingFang TC、Windows 的 Microsoft JhengHei,並搭配通用 sans-serif fallback;使用裝置上已安裝的字型不需額外下載。對很多內容型網站來說,這其實是性價比很高的選擇,尤其當網站的主訴求是資訊傳遞而非視覺衝擊。
WordPress 站長的 webfont 實戰
講到實作面,根據 W3Techs 的統計(2026 年 6 月),WordPress 在全球內容管理系統市場占有很高比例。因此,WordPress 的字體優化做法值得獨立講一段。
WordPress 處理字體的常見痛點是:佈景主題和外掛可能各自載入 Google Fonts 或重複的字重,造成不必要的外部 CSS 與字型請求。用 PageSpeed Insights 或 DevTools 盤點實際請求後,再移除重複或未使用的字型,才能知道對 LCP 的真實影響。
實戰上有三條路可以選:
- 本機託管 Google Fonts:在授權允許下,把原本的字型檔放到自己伺服器,用
@font-face載入。好處是能自行控制子集、快取與第三方連線;但本機託管不保證一定更快,也不等於網站自動符合 GDPR,仍要依整體資料處理方式評估。完整的做法寫在WordPress 本機託管 Google Fonts這篇,一步步帶你做。 - 用外掛自動優化:如果不想動程式碼,有些效能外掛能把 Google Fonts 改成本機託管,或為仍使用的第三方來源加入 resource hints;本機字型不需要對 Google 網域加 preconnect。選外掛時注意別裝太多功能重疊的,可以參考WordPress 外掛推薦清單。裝外掛的方法看這篇外掛安裝教學。
- 佈景主題層級控制:不少現代佈景主題(例如 Astra)本身就提供字體優化選項,讓你在後台直接選字型、調字重,不必手改 CSS。Astra 的操作可以看Astra 主題教學。用 Divi 架站的人,則可以照Divi 的自訂字型上傳流程把品牌字型掛上去。
不管走哪條路,記得一件事:優化完之後要用測量工具驗證。用網站速度測試工具跑一次,看字型請求數量、下載量、LCP 有沒有改善。沒有測量,就不會知道優化到底有沒有效。如果你的站整體偏慢,不只是字體問題,建議把網站速度這條線的細節和網站慢的診斷解法一起對照著看。
進階技巧:讓字體和快取、延遲載入聯手
字體優化做到一個程度,會發現它和其他效能技術是環環相扣的。單獨看字體能擠出的空間有限,但把它放進整體效能策略裡,效果會疊加。
第一個搭檔是快取。字型檔是那種「下載一次就能重複用很久」的資源,非常適合用長快取。在 HTTP 標頭設 Cache-Control: max-age=31536000(一年),搭配檔名加上 hash(例如 noto.abc123.woff2),檔案更新時換檔名即可;MDN 的 Cache-Control 文件有完整說明。這樣回訪者幾乎不用重新下載字型。快取的完整設定看網站快取指南。
第二個搭檔是延遲載入。捲動才會出現的字型(例如頁尾的裝飾字、折疊區塊的特殊字),不用在頁面一開始就下載。可以用 JavaScript 監聽捲動或 Intersection Observer,等該區塊即將進入視窗才觸發字型下載。這個觀念和圖片延遲載入是一樣的,做法可以參考Lazy Loading 延遲載入指南。
第三個搭檔是圖片優化。聽起來不相干,但圖片和字型搶的是同一條網路頻寬。圖片壓好、字體子集化好,兩者一起做,LCP 才會真正漂亮。圖片的壓縮工具和格式選擇,看圖片壓縮工具推薦和WordPress 圖片優化。
這裡的核心觀念是:效能優化是系統工程,單點修改只能治標。字體、圖片、快取、CDN、延遲載入的效果會因頁面與網路而異,應一起量測才能找出真正瓶頸。正因如此,做網站優化要有全盤的視野,千萬別等 PageSpeed 哪一項紅了才頭痛醫頭、腳痛醫腳。
常見的地雷與迷思
這裡整理幾個反覆出現的字體相關錯誤,幫你少走冤枉路。
迷思一:字型越多越有設計感。前面講過了,字型家族應盡量精簡,只保留有明確用途的正文、標題或裝飾字。掛太多字型容易造成視覺混亂、增加下載量與維護成本。
迷思二:貼上 Google Fonts 的 <link> 就一定是最快。Google Fonts 目前產生的嵌入範例通常包含對 gstatic.com 的 preconnect,也會用 unicode-range 分片;固定文字還可用 text= 最小化請求。但仍要只選實際需要的家族與字重,並在目標環境比較第三方託管和本機託管,不能預設其中一種一定更快。
迷思三:字型授權隨便用沒關係。這是法律地雷。很多漂亮的商業字型,授權是不允許 webfont 嵌入的,或要求按域名、按流量計費。把買來的桌機字型直接轉成 webfont 掛上網,等於公開散布,可能吃侵權官司。用之前一定看授權條款。
迷思四:字型只影響美觀,不影響效能。字型載入可能影響 LCP 與 CLS。Google 在 Search Central 的說明中指出,良好的 Core Web Vitals 有助於搜尋成功與使用體驗,但頁面體驗只是眾多因素之一,相關性更高的內容仍可能排名較前。不能宣稱跳出率或停留時間會直接回饋排名,也不能把字型優化當成排名捷徑。它本質上是效能與閱讀體驗工作;想理解更完整的 SEO 脈絡,可以從WordPress SEO 全攻略看起。
迷思五:已經用了系統字,就不用管字體優化。系統字確實零下載,但很多佈景主題或外掛會在你不知情下偷掛 webfont。定期用瀏覽器開發者工具的 Network 面板,篩選 Font,看看你的頁面實際載了哪些字型檔。很多時候會嚇一跳。要是查到字型檔卻對不上畫面上的文字,再用網頁字型辨識工具在頁面上點出字體名稱與字重,來源就對得上了。
迷思六:字型只管好不好看,不用管閱讀性。字型、字級、行高與段落留白會一起影響閱讀體驗,但不能把停留時間或完讀率直接稱為 Google 排名訊號。正文字級與行高也沒有適用所有裝置的固定數字,應依字型特性、版面寬度、語言與實機閱讀測試調整。選字型時若不一起考慮這些排版參數,再漂亮的字也很難發揮價值。
字型策略決策矩陣:什麼情況用什麼做法
前面講了這麼多技術,這一張決策矩陣幫你整合成「什麼情況用什麼做法」。不是每個網站都需要可變字體或動態子集化,關鍵是匹配你的網站類型和需求。
| 網站類型 | 內容特性 | 字型需求 | 推薦策略 | 技術組合 |
|---|---|---|---|---|
| 形象站、登入頁 | 文字少、設計重 | 品牌字型優先 | 本機託管商業字型,子集化到常用字 | WOFF2 + 靜態子集 + font-display: block(主標題)+ preload |
| 內容型網站 | 文章多、文字密集 | 閱讀性優先 | 開源字型(思源黑體)+ 動態子集化 | Google Fonts + font-display: swap + unicode-range + preconnect |
| 電商、SaaS | 功能多、轉換導向 | 速度優先 | 系統字為主,關鍵元素用 webfont | 系統字 + 最少 webfont(只 Logo/CTA)+ optional + 延遲載入 |
| 多語系站 | 中英文內容 | 各語系獨立優化 | 拆分字型檔,按語系載入 | unicode-range + 分別子集化 + CDN |
| 品牌官網 | 設計一致、高流量 | 品牌一致性 | 可變字體 + 本機託管 + 靜態子集 | Variable Fonts + WOFF2 + font-display: swap + Service Worker 快取 |
這張表的核心邏輯是:問自己「這個網站的成功關鍵是什麼?」如果是品牌形象,就願意為字型付出更多下載成本;如果是速度和轉換,就盡量用系統字和最小化的 webfont;如果是內容型網站,就平衡閱讀性和速度,用開源字型加子集化。
另一個維度是「流量規模」。高流量站縮小每次回應的傳輸量,累積後可能降低 CDN 頻寬成本;但檔案大小不會直接改變請求次數。這時候字型子集化和壓縮不只是效能問題,也是成本問題。建議定期做字型審查,看有沒有冗餘的字重或沒在用的字型可以移除。
怎麼診斷字體效能問題:DevTools 實戰
要確認網站是否有字體問題,可以用 Chrome 開發者工具走一次診斷流程,直接查看實際載入的字型檔、請求時序與版面位移。
第一步,打開你要檢查的頁面,按 F12 或在頁面按右鍵選「檢查」打開 DevTools,切到 Network 分頁。在資源類型篩選按鈕裡選 Font,重新整理頁面。你會看到這一頁載入的所有字型檔清單,每個檔案的 Size、Time、Waterfall 都一目了然。重點看總共載入哪些家族與字重、各有多大、是否重複,以及下載時間落在瀑布圖的哪個位置;沒有適用所有網站的固定請求數或單檔容量門檻。
第二步,切到 Performance 分頁,按錄製鈕跑一次頁面載入。錄完後對照 Network track 的字型請求、Main track 的 Render/Paint 事件與 LCP 標記,判斷字型是否延後文字繪製。如果 LCP 元素是使用 webfont 的標題,就進一步比較字型請求與該元素繪製的時序。
第三步,用 Lighthouse 跑一次報告(DevTools 裡的 Lighthouse 分頁,或直接用 PageSpeed Insights 線上版)。自 Lighthouse 13 起,舊的「Ensure text remains visible during webfont load」稽核已移到 Font display insight;若出現提示,應檢查 font-display 與 fallback 策略,而不是一律套用同一個值(見 Chrome Developers 的稽核說明)。
第四步,檢查 CLS。在 DevTools 的 Performance 分頁使用 Live metrics 與 Layout shifts track,查看位移分群、受影響元素與可能原因。Web Vitals Chrome 擴充功能已在 2025 年停止支援,相關功能已整合到 Performance 面板(見 Chrome Developers 的公告)。如果位移集中在字型替換的瞬間,再調整備用字與 font-size-adjust。
這四步走完,對自己網站的字體健康度會有清楚的數字依據,不再憑感覺判斷。測試時應固定裝置與網路節流條件,視需求停用快取或另外測試冷、暖快取,並重複執行;桌機和手機也要分開測,因為兩者的實際結果可能不同。想知道更多測速工具的比較,可以看網站速度測試工具這篇的完整評比。
字體優化行動清單:七步把字型效能拉起來
講了一整篇,給你一份能照著做的行動清單。這是評估網站字體健康度時會走的流程:
- 盤點現況:用瀏覽器 DevTools 的 Network 面板,篩選 Font,列出你網站目前載了哪些字型檔、各多大。這一步會讓你清楚問題在哪。
- 砍掉不必要的字型:只保留有明確用途的字型家族。裝飾用的手寫體、特殊字型,能用系統字替代就替代。
- 挑對字重:不要掛整套字重(細體、常規、中等、粗體、特粗全上),只留實際用到的字重。靜態字型通常每個字重各有資源;若用可變字體,則比較實際傳輸量。
- 子集化:中文字型應優先評估。用 pyftsubset、Google Fonts 的分片或
text=機制移除不需要的字形,並實測縮減幅度。 - 設 font-display:正文若優先避免文字隱藏,可先評估
swap;品牌字與裝飾字則依可接受的替換、延遲與版面位移選擇block或optional,不要不經測試就套用同一設定。 - 加 preload 和 preconnect:關鍵字型加
preload,第三方網域加preconnect。別忘了crossorigin。 - 壓 CLS:挑尺寸接近的備用字,用
font-size-adjust,為標題區預留高度。然後以真實使用者資料的第 75 百分位數驗證 CLS 是否達到「良好」門檻 0.1 以下。
做完這七步,字體載入策略大概已經貼近業界水準。剩下的就是持續監測,每加新字型或換佈景主題時,重新走一次這個流程。
字體這件事,本質上是「用最少的下載成本,換最大的視覺質感」。它真正考驗你的,是在設計和效能之間做理性取捨的判斷力,CSS 語法反而是最簡單的一環。這種取捨能力,其實就是好的網頁設計和好的UI/UX的核心。當你把字體、色彩(見網站配色指南)、版面(見網頁版面設計)這幾個變數都調到平衡,網站的整體質感自然會出來,而且不必拿速度去換。
把字體當成網站的基礎建設來管理,能減少不必要的下載與版面位移。打開網站的 DevTools,先看看實際載入了哪些字型檔,再決定要刪減、子集化或調整載入策略。
如果正在從零開始架一個新站,恭喜你,字體策略從頭規劃,通常比事後補救輕鬆。從WordPress 快速架站到Astra 品牌網站搭建,一開始就把字型數量、字重、子集化、font-display 這幾件事設定好,之後就不用反覆回頭救火。