1. 程式人生 > 其它 >CSS3 使用@font-face引入字型的相容性方案及優化

CSS3 使用@font-face引入字型的相容性方案及優化

引入第三方字型一定要注意字型版權問題

前言

承接上文web 端字型相容性適配之後,好久沒有總結 CSS3 引入字型 @font-face 相關的文章了。一是在掌握 @font-face 的基本使用要領後沒遇過相容性問題,二是覺得 @font-face 已經相容 ie9+及現代瀏覽器了,相容性問題基本可以忽略不計了。事與願違的是,在多次實戰中發現引入第三方字體會出現許多奇形怪狀的問題,譬如字型檔案的編碼問題引發字型可以在桌面系統正常使用而在 Web 端不起作用、字型檔案中英文或其他外語的字型行高差異問題、字型檔案的等寬比在不同瀏覽器顯示差異問題......現對web 端字型相容性適配作補充,如果不妥請各位大佬抬手指正(#.

#)。

字型相容性

字型編碼相容

前段時間有幾個需要引入第三方字型的專案,引入過西文、韓文、泰文、以及種類繁多讓你眼花繚亂的中文字型,可能是因為引入那種中文字型比較多的緣故吧,老覺得中文字型的相容性可能會多些,其中編碼相容性像一座大山。

或許你會遇到過這樣的情景,字型在 Photoshop 可以正常使用,放在 Web 端通過 @font-face 引入後字型顯示不起作用。與相似的還有引入字型在 IE、Firefox 等瀏覽器正常使用,在 chrome 瀏覽器卻顯示編碼報錯不起作用如:OTS parsing error: cmap: Failed to serialize table的情況,或者完全因為字型編碼格式不是被該瀏覽器所支援。

“工欲善其事必先利其器”,解決編碼問題最直接的辦法當然是將字型轉碼處理了。這裡推薦兩個字型轉碼工具:

只需將字型轉化為需要的字型格式即可,另外推薦使用.ttf格式,用途下面有細講。

字型優化

字型壓縮

字型檔案體積一般少則 2~4M,多則能達到 20~30M 之多,因此 直接 引入第三方字型尚且存在很大缺陷,尤其是在移動端使用。

當然開發者的智慧是無窮的,社群對此類問題也提供了字型壓縮的解決方案。

常用字型壓縮有:

  • font-spider
  • fontmin

上述字型壓縮工具的核心是,通過抽離指定預設的字串來生成新的字型檔案,因為排除了大量不需要的字串集,抽離後的字型檔案體積大大變小,從而達到字型壓縮的效果。

font-spider

使用font-spider已經有幾年時間了,用著方便也是比較推薦使用的。

詳細的使用方法可以檢視font-spider 官網

font-spider的主要用途是 將 .ttf 格式的字型檔案根據需求預設 css 字型格式來生成字型檔案。

特別注意的是,font-spider 只能將 .ttf 格式的字型檔案轉化為其他格式的字型檔案。

fontmin

最近身邊有同學也在使用 fontmin 來轉化字型格式,因此也貼出來供大家參考食用。

詳細的使用方法可以檢視fontmin 官網

fontminfont-spider 的最大差異是,前者不需要指定.ttf 格式的字型檔案進行轉化,而是通過其配套的字型轉化外掛來定製使用。

使用 rel="preload" 優化字型載入

由於自定義字型只有當前頁面被引用到的時候,瀏覽器才會對字型進行載入。為了更快的載入字型檔案,可以使用rel="preload"來達到效果

<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin />

FOUT(Flash of Unstyled Text) 優化

FOIT(Flash of Invisible Text)問題:瀏覽器在載入字型的時候的預設表現形式,也就是在字型載入過程中,頁面是看不到文字內容的。在現代瀏覽器中,FOIT 會導致這種現象出現至多 3 秒。FOIT 會導致很差的使用者體驗,這是我們需要儘量去避免的。

FOUT:在字型載入過程中使用預設的系統字型,字型載入完後顯示載入的字型,如果超過了 FOIT(3s)字型還沒載入,則繼續使用預設的系統字型。

FOUT 特性:

  • 通過 @font-face 設定 屬性 font-display 來實現,預設為 auto。
  • IE 瀏覽器和 Edge 不會等待 FOIT 超時才顯示預設字型,會立即顯示預設字型。FOUT 比 FOIT 好,但是需要注意它引起的 reflow。

為了實現 FOUT,一般可設定 font-displayswapfallbackoptional

  • swap:為字型提供一個非常小的阻塞週期和無限的交換週期。(自定義字型載入成功即顯示字型樣式,可以在頁面中看到的一個字型替換的效果)
  • fallback:為字型提供一個非常小的阻塞週期和短暫的交換週期。(Gives the font face an extremely small block period (100ms or less is recommended in most cases) and a short swap period (3s is recommended in most cases).)
  • optional:為字型提供一個非常小的阻塞週期,並且沒有交換週期。(Gives the font face an extremely small block period (100ms or less is recommended in most cases) and a 0s swap period)
@font-face {
  font-family: 'fcustom';
  font-display: 'swap';
  font-display: 'fallback';
  font-display: 'optional';
}

使用監聽字型載入

FontFaceObserver

通過使用外掛 npm i fontfaceobserver 來監聽字型載入完成,從而按需設定字型樣式。

在字型載入前預算一種字型或使用 loading 效果什麼的,字型載入成功後切換字型即可

// css 中 @font-face 已定義好
import FontFaceObserver from 'fontfaceobserver';

function loadfont() {
  var ffo = new FontFaceObserver('My Family');
  ffo.load().then(() => {
    document.getElementById('fcustom').style.fontFamily = 'My Family';
  });
}

Font Load API

方法效果同 FontFaceObserver。

使用 Font Load API 載入字型,字型在載入完成前預算一種字型,字型載入完成切換相應的 CSS 即可。

但是需注意 Font Load API 是原生的 API,有相容性問題。

<script>
  document.fonts.load('1em open_sansregular').then(function() {
    var docEl = document.documentElement;
    docEl.className += ' open-sans-loaded';
  });
</script>

<style>
  .open-sans-loaded h1 {
    font-family: open_sansregular;
  }
</style>

字型轉 BASE64URI

核心要義就是將@font-face 中定義字型時的路徑直接改為字型的 base64 編碼。

  • 優點:因為不會產生 FOIT 和 FOUT。所以不會有 reflow 和 repaint。
  • 缺點:
    • 字型轉成 base64 也會很大,會影響頁面首次載入速度。
    • 不支援逗號分隔的形式載入多種格式的字型,只能載入一種格式字型。這導致你為了儘可能保證所有瀏覽器都可以相容,通常會指定為 woff 格式,因為 woff 格式相容性好,但是卻沒法使用更小體積的 woff2 格式,因為 woff2 格式相容性差點。

非同步載入 BASE64 格式 URI 字型

通過非同步的方式插入帶有 BASE64 格式 URI 字型的 CSS 連結。

更多詳情請前往原文-CSS3 使用@font-face 引入字型的相容性方案及優化

相關文獻