Webフォントがブラウザで有効か?きっちり調べる
「古典的な方法」に加筆修正しています。(2024/01/27)
内容が重複する記事「アイコンの為に Web フォント、合字を深堀してフォールバックを検討する」を公開しました。(2024/01/26)
テーブルに WOFF2 を追記しました。(2023/07/01)
フロー図を追加して、若干の追記と推敲を行いました。(2022/10/06)
#BLM を支持し「ブロックリスト」への書き換え。webfontTest.js へのリンクの修正。(2020/8/31)
趣味の Web 開発でも使う為いよいよガッツリ調べました。Web フォント無効を検出してフォールバックを実施したい場合、どのような判定法があるのでしょう?
調べている間に知りましたが、ここで紹介する手法は Canvas
要素に Web フォントでテキストを書きたい場合にもマストです。Web 開発は罠が多いですね。
Webフォントのサポートブラウザ
以下の表は 『LucasFonts | Webfonts』のもので、記事はさらに caniuse を元にしています。誤りがあったため、私の方で修正と追記を行っています。
WOFF2 | WOFF | EOT | SVG | TTF | OTF | |
Safari | 10(*2) | 5.1 | 3.2 | 3.1 | 3.1 | |
iOS Safari | 10 | 5.0 | 3.2 | 4.2 | 4.2 | |
Firefox | 39 | 3.6 | 3.5 | 3.5 | ||
Firefox for Android | 39 | 15.0 | 15.0 | 15.0 | ||
Chrome | 36 | 5.0 | 4.0 | 4.0 | 4.0 | |
Chrome for Android | 36 | 18.0 | 18.0 | 18.0 | 18.0 | |
Internet Explorer | 9.0 | |||||
IE Mobile | 10.0 | |||||
Opera | 11.1 | 10.0 | 10.0 | |||
Opera Mini | 〇 | |||||
Opera Mobile | 11.0(*1) | 10.0? | 10.0? | 10.0? | ||
Android Browser | 4.4 | 3.0 | 2.2 | 2.2 | ||
Blackberry Browser | 7.0 | 7.0 | 7.0 | 7.0 |
- 『Opera Mobile 11 for Android and Symbian』
Support for Web Open Font Format (WOFF), Support for Arabic ligatures
Supported only on Safari for Mac OS Sierra, not El Capitan & older.
部分追記
IE は正しくは4.0以降からサポートします。
Opera は9.0から SVG フォントをサポートする、とありましたが手元の環境では確認できませんでした。『Opera Presto 2.2 と Opera 10 概観 - Dev.Opera』では10から Web フォントと SVG Web Font をサポートしているようです。
私達は古い(そして新しい)モバイル・ブラウザー―例えば Opera Mini や Nokia XPress Browser, Blackberry 4-5, Android 2.1, Windows Phone 7-7.8―が
@font-face
をまったくサポートしていないことを発見しました。
Web フォントが有効か?判定する
Web フォントが無効のケースには次の3パターンが考えられます。
- そもそもブラウザが Web フォントに対応していない
- ユーザーの設定によって Web フォントが切られている
- 通信量削減用のネットワーク監視アプリ等で Web フォントのダウンロードが制限されている
残念ながら無効の場合、画像や SVG、Pure CSS アイコン、記号文字(グリフ)によるフォールバックが考えられます。画像の表示を禁止するユーザー設定やアドオンもありますし、便利な記号文字は大抵機種依存です。ムキになると際限がありませんね…
フォールバックに使うグリフは細心の注意を払って決定しましょう。クロス・ブラウザー及びクロス・プラットフォームであるかはグリフによって違います。John Holt Ripleyの互換性の表を参照してください。
1. そもそもブラウザが Web フォントに対応していない
この判定には Modernizr にある機能判定が有効な場合もありますが、これをすり抜けるブラウザもあるため Modernizr でも初めにブロックリストで弾いています。
ブロックリスト
参考になるのは Modernizr です。最新のコードでは古い Android の判定を削除しているため、以前のコードにリンクしています。
併せて更にマイナーなブラウザも調査している『Testing @font-face Support on Mobile and Tablet』を参考にするのが良いでしょう。
そもそもマイナーなブラウザまでカバーする判定には拙著『「デスクトップ版を表示する」にチェックを付けると平然とUAを偽装するAndroid用標準ブラウザの判定をムキになってしてみます』で紹介しているコードを一旦お勧めします。navigator.uaserAgent
文字列の偽装にもある程度の耐性があります。
@font-face
の機能判定
@font-face
の判定コードは削除済です。これは動的判定を減らし、ブラウザエンジン・バージョン検出と機能カタログを組み合わせた静的判定を重視する web-doc-base の開発の大方針に沿っています。(2022/10/06 追記)
Modernizr を参考にします。
2. ユーザー設定によって Web フォントが切られている
Web フォントを無効にすると @font-face
を StyleSheet
に追加できなくなる事例を確認していない上に、@font-face
機能判定を削除済につき、この部分は意味をなさなくなりました。(2022/10/06 追記)
ユーザー設定によって無効になっている場合、機能判定の時点で判断できると思われます。もしブラウザがそのような実装になっていない場合、後述の実測によって最終的な判断をします。
3. 通信監視アプリ等で Web フォントのダウンロードが制限されている
通信量の削減やセキュリティの為に通信監視アプリやアドオン等で Web フォントのダウンロードを禁止されているケースが考えられます。この場合、CSS に埋め込む等で監視をすり抜けることができます。
データ URI で CSS に埋め込んだ Web フォントは機能するか?
データ URI な Web フォントが使用可能か? CSS にあらかじめチェック用の Web フォントを埋め込んだり、javascript から動的に書き出して確認します。
但し、無用な通信をしたくない、というユーザーの意思をまずは尊重し、巨大な日本語フォントセットをダウンロードする様なことは控えましょう。小さなアイコンフォントに限るなど抑制的な利用に留めましょう。
そもそもデータ URI が使えるか?の判定には Modernizr が参考になります。また IE8 以下では画像ファイルしか扱えない、という制限があるためあらかじめ除外します。
Web フォントが有効になった?実測による判定
Web フォントが有効になるタイミングを知るには、新しい API document.fonts
を備えている場合はこれを利用できます。非対応の場合、隠し要素を測定して判定するという古典的な方法を用いて Web フォントが有効であることを確定させます。
しかし document.fonts.load().then()
で必ずしも検出できる訳では無いようで、古典的な方法を併用します。詳しくはソースコードを確認ください。(2022/10/06 追記)
document.fonts
を使う方法
bramstein > fontfaceobserver > observer.js などを参考にします。
observer.js の document.hidden
の扱いが釈然としない為、僕のコードでは document.hidden == true
で測定時間を延長する実装にしています。モバイル Firefox では、背面に回ったタブの Web フォントのロードやレンダリングを休止する動作をすると思うのですが… (2022/10/06 追記)
古典的な方法
『JavaScript/CSS Font Detector』で紹介されているコードが参考になりますが、そのままのコードでは Webkit で判定に失敗するため 。monospace
を外しました。同様の報告は『canvas要素にwebフォントを確実に描画する方法』のコードのコメントにもありましたmonospace
を外す対処法はいまいちです。原因とより良い対処法は WebKit フォールバックバグを参照します。(2024/01/27 追記)