スキップしてメイン コンテンツに移動

アイコンの為に Web フォント、合字を深堀してフォールバックを検討する

Firefox では、インラインスタイルを使わないと、要素の計測を使った Web フォントの適用判定に失敗します。(2024/06/19)

表の修正。「AOSP」→「Android WebView ~4.4.4」など。(2024/03/02)

Web フォントをサポートするゲーム機用ブラウザの情報を追記しました。但し PS5, New 3DS, Xbox One, Xbox Series X|S については端末を所持していないため未調査です。Xbox 360は未調査です。(2024/02/06, 02/07 表の誤りの微修正)

「FontFaceDetector → Font Face Observer」誤記の修正とリンクの追加。(2024/02/04)

Android x86 4.4.2の調査結果を元に AOSP の WOFF のサポートバージョンを微修正。(2024/02/01)

WebKit フォールバックバグ」について追記しました。「SVG フォントの制限」についてカラムを追加しました。(2024/01/27)

3行まとめ

  1. Can I use, browser-compat-data は必ずしも正しくはない。
  2. サポートするフォント形式の開始時期と終了時期の他にも、微妙な差異として合字周り、Data URI、SVG に関するものに加えて、絵文字の可否、WebKit フォールバックバグの有無が見つかりました。
  3. 合字を使う場合 Chrome 1~14, Safari 3.1~5.1, AOSP 3~4.3では SVG フォント一択です。

はじめに

このブログのアイコンを「Pure CSS アイコン」から Web フォントと動的 SVG の2段構えによる「ベクターアイコン」へ変更中です。

これにあわせて、Web フォントのロード監視コードを見直しました。

ブラウザがサポートするフォント形式を動的調査からカタログ方式へ

draw.io で編集する

以前のコードはブラウザがサポートするフォント形式を動的に調べていました。 この為にとても小さい Data URI 化したフォントを CSS に組み込んでいました。しかし、僕の用意した小さいフォントでは動作せず、アイコンフォントを Data URI 化したものは動作するケースがありました。

この原因の特定が僕の手には余ったこともあり、CSS を太らせる小さいフォントの利用は止めて、ブラウザ毎にサポートするフォント形式のリストを持つことにしました。

この他にもテストページを使った検証作業で、寡聞にして言及されているのを知らない差異を発見しました。Web フォントを使用しているデベロッパー諸賢は、併せてよくご覧ください。

Data URI 化した Web フォントを使用する先行事例

同様に Data URI 化した Web フォントを使用している RoelN / font-face-render-check プロジェクトがありました。こちらの最小フォントで試したところ、僕の用意したものとは結果が異なりました。

また font-face-render-check は「@font-face Feature Detection」を参考にしているとのことです。

テスト結果

? マークは暫定のバージョンです。Can I use のバージョン番号をそのままコピーして来た場合、括弧内に記載しています。

フォント形式をサポートするバージョン

ブラウザWOFF2WOFFTTF, OTFSVGEOT
制限(*1)
IE, EdgeHTML14(Can I use)99--4
Presto Opera-11.5010.1011.50(*1)~12.x-
Gecko39(Can I use)1.9.21.9.1---
Safari10(Can I use, *7)5.03.13.1(*1)~3.x-
iOS Safari(*6)10(Can I use)5.0(Can I use, 6.1で〇)43.1(*1)~4-
Chrome36621~36(*1, *2)~5-
Android WebView ~4.4.4-4.4.0(*4)2.2(*3)3.0(*3)--
Chrome for WebView(*5)373737---
PS4 WebKit 605.1.15, 11.0---
PS Vita WebKit 537.73, 3.74---
PS3 WebKit 531.22.8, 4.90---
Switch WebKit 609.4---
WiiU WebKit 536.30---
  1. SVG フォントの制限について詳しくは「svgo を使って SVG フォントを最適化する、その際の注意点は? / <font> タグの id 属性は残す / SVG フォントの制限」参照。
  2. Chrome 38 and newer support SVG fonts only on Windows Vista and XP. Can I use では Chrome ~37 となっている。多分誤り。ただし動作確認はポータブル版の Iron で確認している。Windows XP + Iron では39までサポートする。
  3. Android 2.3, 3.1実機で確認。
  4. Android x86 4.4.2, 4.4.4で確認。
  5. Android x86 5.1.1 Chromium M39 で確認。
  6. iPod touch 実機 3.1.3, 4.2.1 6.1.6 で確認
  7. Supported only on Safari for Mac OS Sierra, not El Capitan & older. ちなみに Sierra のバージョン番号は10.12

合字、絵文字への割り当て、Data URI、WebKit フォールバックバグ

合字をサポートするブラウザの中には、アルファベットの文字列のみをサポートするもの(合字 1)から、記号の組み合わせをサポートするものまで何段階かあるようです。

ブラウザ合字 1合字 2合字 3絵文字Data URIWebKit フォールバックバグ
IE, EdgeHTML18?18?18?89-
Presto Opera10.10--10.5010.10(*1)-
Gecko1.9.11.9.12.01.9.11.9.1b3(*12)-
Safari(*8)3.1(*5)3.1(*4)3.1~6.x(Font Face Observer より)
iOS Safari3.1(*11)(6.1でも-, 12.5で〇)(6.1でも-, 12.5で〇)3.14.2~6.1
Chrome(*8)1(*6)15(*7)34(*7)12(*2)9~17
Android WebView ~4.4.43.0(*3, *9)--2.2(*3)2.2(*3)~2.3
Chrome for WebView(*10)37373737-
PS4 WebKit 605.1.15, 11.0SVG:一部, 他:〇-
PS Vita WebKit 537.73, 3.74SVG:〇, 他:---SVG:〇, 他:一部-
PS3 WebKit 531.22.8, 4.90SVG:〇, 他:---
Switch WebKit 609.4SVG:-, 他:〇---
WiiU WebKit 536.30SVG:〇, 他:---SVG:〇, 他:一部-
  1. 但し、テスト用の最小フォントでは何故か不可
  2. 4~5 テスト用の最小フォントでは何故か不可、6~31 テスト用の最小フォントは SVG のみ
  3. Android 2.3, 3.1実機で確認
  4. Safari 3.x では SVG フォントのみ、4.0 以降では全てのフォント形式で有効
  5. SVG フォントのみ(3.x, 4.0.5, 5.1.1 で確認)
    • Chrome 1~14では合字は SVG フォントのみ。
    • TTF, OTF, WOFF には -webkit-font-feature-settings:"liga"; が必要。一方の SVG フォントはこのプロパティが不要。
  6. SVG 形式を除く
  7. Safari 3.xと Chrome 1は SVG フォントのみ、合字1, 合字2, 合字3 が有効だった。
  8. SVG フォントのみ(3.1実機, 4.2.2実機, Android x86 4.3で確認)。4.4.0では他のフォントも(Android x86 4.4.2, 4.4.4で確認)。
  9. Android x86 5.1.1 Chromium M39 で確認。
  10. SVG フォントのみ(iOS 3.1.3, 4.2.1 6.1.6 で確認)
  11. 1.9.1b1 不可, 1.9.1b2 未確認

1. 合字

てっきり font-feature-settings:"liga" をサポートするブラウザで使用可能かと考えていましたが、思ったよりも古いブラウザから合字をサポートしています。JavaScript でフォールバックするブラウザの範囲はかなり絞られるようです。

部分的合字サポート

しかし、文字列によっては合字しない「部分的合字サポート」のブラウザが存在します。これに該当するブラウザは、ページ上に存在する全ての合字の描画状況を JavaScript で調査してフォールバックします。

2. 絵文字にフォントを当てる事が出来るか

Web フォントが読み込まれない場合にも、元が絵文字であれば影響が最小と考えました。しかし案の定、絵文字には Web フォントが当たらないブラウザが見つかりました。IE7 以下、Opera 10.5 未満、Safari 3.x の TTF, OTF が該当します。

副作用の少ない空白文字のセットを探す

この結果を承けて僕のブログでは、空白文字にアイコンフォントを割り当てる方向で考えていきます。因みに空白文字が豆腐になったり、点になるブラウザも存在します。44個の空白文字の内、IE5 で綺麗に空白になる22個を見つけたので、これに割り当てていきます。

3. Data URI スキーム

4. WebKit フォールバックバグ

初期の WebKit は、Web フォントの適用前の状態が他のブラウザと異なります。この為に「伝統的な Web フォントの適用の検出法」が使えません。

一部の WebKit では Web フォントの適用前に「最後の手段フォント(Last Resort Font)」が使用される為に、伝統的な検出法を欺いてしまいます。これを回避する為に一部の WebKit では異なる検出コードを用います。

この詳しい挙動と解決法については Font Face Observer の Observer.hasWebKitFallbackBug を参照しましたFont Face Observer では Webkit 536.11 以下(Safari 6に相当)に対して異なる検出コードを用いています。しかし UserAgent 文字列のバージョンを調べる簡易な方法では Webkit の派生ブラウザをカバーしきれません。ご覧の通り、本記事では同時代の様々な WebKit ブラウザについてフォールバックの必要なバージョンを特定しています。

iOS 4.2で検出に失敗する問題

このコードを用いても iOS 4.2では5秒のタイムアウト迄に Web フォントが適用されない問題に遭遇しました。原因は setTimeout のインターバルを 16ms にしていた為で、64ms に変更したところ、iOS 3や iOS 6と挙動が一致し検出ができるようになりました。iOS 5では端末を所持していなくて確認出来ていません。

iOS 4では、文書読み込み時などの忙しい時に、短いインターバルを設定してしまうと、Web フォントの処理が極端に後回しにされてしまうようです。32ms でも問題に遭遇することを確認しています。

因みに Font Face Observer ではタイマーではなく、より巧みな scroll イベントで Web フォントの適用タイミングを検出しているため、この問題を踏んでいません。

最後に

本記事で示した対応表は Can I use 提供のソレと微妙に一致しません。Can I use が参照している browser-compat-data も怪しいデータはあるので、やはりブラウザをインストールして愚直な調査が重要ということです。

iOS 5のインストールされた iPod touch 第三世代が入手困難なのと、Genymotion が古い Android のサポートを切っていくのに難儀します。頑張って行きましょう。

参考記事

  1. 安全な @font-face の書き方
  2. @font-face web font research