michimani.net

Adobe Fonts で Web フォントを適用するときに発生するチラツキを無くす

2018-12-19

Adobe Fonts (旧 Typekit) を利用して Web フォントを適用する際に、ページの描画と Web フォントが適用に若干のタイムラグが発生し、画面がちらつくことがあります。
これは、 Web フォントが適用されるまでの僅かな時間にシステムフォントによってページ内のテキストが描画されるからです。

僅かな時間とは言え、フォントによっては幅や高さが異なりテキストが表示されるエリアの見た目にも関わってくる部分なので、できればこのチラツキはなくしたいです。

ちなみにこのチラツキのことを FOUT (Flash Of Unstyled Text) と呼ぶみたいです。

やりたいこと

Web フォントの適用が完了してからページを描画すれば、チラツキはなくなります。なので、最初はページ全体を非表示にしておいて、 Web フォントがロードできた タイミングでページ全体を表示すれば OK です。
ただし、仮に Web フォントのロードが完了しなかった場合は いつまでたってもページが表示されないので、その場合については考慮する必要があります。

この Web フォントがロードできた ことをどうやって検出するかですが、 Adobe Fonts では非常に簡単な方法でそのタイミングを知らせてくれています。
Adobe Fonts の Web フォントでは、 Web フォントがロードできたタイミングで、 html タグに wf-active という class を追加してくれています。(厳密には他にも class を追加しています)
なので、この class の有無で Web フォントがロードできたかどうかを判定することができます。

やること

CSS の記述

class によって Web フォントのロード完了を検出できるので、下記のようなスタイルを適用させます。

html {
    visibility: hidden;
}

html.wf-active,
html.loading-delay {
    visibility: visible;
}

これによって、 class に wf-active を持つ html のみ表示されるようになります。ただし Web フォントのロードが完了しない = html タグに class wf-active が追加されないと、ページが表示されません。
html.loading-delay については、その対策として使用します。

JavaScript の記述

Web フォントのロードが完了しない場合に備えて、次のような処理を実装します。

setTimeout(function() {
    if (document.getElementsByTagName("html")[0].classList.contains('wf-active') != true) {
        document.getElementsByTagName("html")[0].classList.add('loading-delay');
    }
}, 3000);

これによって、 3000 ms (3秒) 経っても class wf-active が追加されていない場合は、代わりに class loading-delay を追加するようにしています。その結果、遅くとも 3 秒後にはページの内容が表示されるようになります。
Adobe Fonts の Web フォント用スクリプトでは、 scriptTimeout の値として 3000 がデフォルトで指定されているので、ここでの指定も 3000 でよいかと思います。が、このあたりは適宜変更で。

結果

このブログでも Adobe Fonts で Web フォントを適用させていたのですが、チラツキがあり見づらい状態でした。が、上記方法でチラツキを無くすことができました。
ちなみにこの方法は Google が提供している Web フォントでもそのまま利用可能なようです。 (同じ方法で Web フォントデータをロードしているらしいです)

Web フォントのサービスには他にも色々ありますが、サービスによっては独自に JavaScript の API でロード完了イベントを取得できたりする場合もあるようなので、この方法が使えない場合はそれを使う方法も考えられそうです。

参考


comments powered by Disqus