[CSS]Web制作者が知っておきたい、Webフォントを快適に表示するCSSの新しいプロパティ「font-display」
Post on:2017年7月26日
Webフォントを使用しているサイトやブログが増えてきました。そして、近日アップデートされるChrome 60では、Webフォントの使い勝手を向上する「font-display」プロパティがいよいよ正式に実装される予定です(参考: Chromium)。
追記: さきほどChrome 60がリリースされました。
Webフォントを適用したテキストが読み込み時に一瞬表示されない現象があり、今まではJavaScriptで対応していた人、仕様だとあきらめていた人は、このfont-displayを積極的に取り入れるべきだと思います。
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
- ブラウザでフォントが読み込まれる仕組み
- font-displayプロパティとは
- ほとんどの場合、swapを使用したいと思うでしょう
- font-displayがサポートされていない場合
- サードパーティのフォントプロバイダについて
ブラウザでフォントが読み込まれる仕組み
わたし達が使用しているブラウザは疑うまでもなく、多くの機能が入念に実装されたプログラムです。その中の一つに、フォントの読み込みがあります。
ブラウザがフォントを読み込む時、そのフォントを使用するようにスタイルされたテキストは、フォントが読み込まれるまで隠されます。これは「FOIT」と呼ばれ、「Flash of Invisible Text」テキストが一瞬見えない現象です。
FOIT: 読み込み時にテキストが一瞬見えない現象
この現象は文字化けしていないテキストの表示を避けるためにありますが、遅い表示がビジターにイライラを感じさせるかもしれません。ほとんどのブラウザはデフォルトで、フォントが読み込まれるのを待つ間にフォールバックテキストを表示するまで、テキストを3秒間隠します。Safariなど他のブラウザではさらに長い時間、レンダリングされないテキストが残されます。
現在この問題を解決する方法は、Font Face ObserverのようなJavaScriptを使用して、フォントが読み込まれた時を追跡することです。最初にシステムフォントを使用して、スタイルを適用します。そして、カスタムフォントがJavaScript経由で読み込まれたことを検出すると、ドキュメントにカスタムフォントを適用するCSSのクラスを与えます。
例えば、すべての<p>タグにOpen Sans Regularを適用するとします。まずは、下記のように指定します。
1 2 3 |
p { font-family: "Arial", "Helvetica", sans-serif; } |
これでフォントが読み込まれると、ArialまたはHelvetica(システムで使用可能なフォントに依存)が最初に表示されます。Open Sans RegularがJavaScriptを使用して読み込まれていることを確認したら、<html>タグにfonts-loadedのクラスを適用します。このCSSはOpen SansをこのCSS経由で<p>タグに適用します。
1 2 3 |
.fonts-loaded p { font-family: "Open Sans Regular"; } |
この方法はうまく機能しますが、扱いにくい場合があります。そこで新しいCSSのプロパティ「font-display」の登場です。
font-displayプロパティとは
font-displayは、Chrome 49で実験的な機能として登場した新しいCSSのプロパティで、OperaやAndroid用のOperaにも実装されています。
【訳者注】
Chromeの次期バージョン、Chrome 60で正式に採用されます。
font-displayを使用することで、JavaScriptベースのソリューションとほぼ同じ方法でフォントを表示する方法を制御することができます。
しかも、たった一行のCSSでOKです!
まずは、font-displayプロパティの値を知っておきましょう。
- auto: デフォルト値。典型的なブラウザのフォント読み込み動作が行われます。これは、カスタムフォントを使用する書体を非表示にし、フォントの読み込みが完了したときに影響を受けるテキストを表示します。
- swap: カスタムフォントが読み込まれるまで、フォールバックテキストはすぐに表示されます。
ほとんどの場合、これがわたし達が求めているものです。 JavaScriptを使用したソリューションのほとんどは、この設定をエミュレートすることを目指しています。 - fallback: これはautoとswapの間の折衷案です。カスタムフォントでスタイルされたテキストが表示されない短い時間(Googleによれば100ms)があり、その後にスタイルのないテキストが表示されます(カスタムフォントがこの時点までにロードされていない場合)。フォントが読み込まれると、テキストのスタイルが適切に設定されます。
- optional: 影響を受けたテキストが最初は表示されず、その後フォールバックフォントに移行するという点で、fallbackのように動作します。しかし、同じなのはそこまでです。optionalではブラウザ側でもフォントを使用するか自由に決めることができ、この動作はユーザーの接続スピードに左右されます。接続が遅い場合にoptionalを指定すると、カスタムフォントがまったく読み込まれないことがあります。
font-displayの値が分かったので、@font-faceルールに適用してみましょう。
Open Sans Regularの@font-face宣言でswap値を指定してみます。
1 2 3 4 5 6 7 |
@font-face { font-family: "Open Sans Regular"; font-weight: 400; font-style: normal; src: url("fonts/OpenSans-Regular-BasicLatin.woff2") format("woff2"); font-display: swap; } |
この例ではWOFF2ファイルのみを使用して指定を省略していますが、ここでは簡潔にする予定です。この例では、font-displayにswapを使用しています。この指定は、下図のように表示されます。
「font-display: swap;」を指定した時の表示
JavaScriptでフォントの読み込みを制御するとき、これがわたし達が求めているものです。テキストがデフォルトで表示されていることを確認してから、カスタムフォントがダウンロードされた後に適用されます。
フォールバックのフォント指定はどのように構成すればよいでしょうか? 要素にfont-familyを指定するときは、コンマ区切りのフォントリストを使用します。フォールバックとは、カスタムフォントの後に指定しているシステムフォントのことです。
1 2 3 |
p { font-family: "Open Sans Regular", "Helvetica", "Arial", sans-serif; } |
この例のフォントスタックでは、カスタムフォントはOpen Sans Regularで、システムフォントはHelveticaとArialです。「font-display: swap;」で最初に表示されるフォントは、最初に指定したシステムフォントです。カスタムフォントが読み込まれると、最初に表示されたシステムフォントが読み込まれ、置き換えられます。fallbackとoptionalの他のfont-displayの値にを使用することは、カスタムフォントで何をするかを決める前に、スタック内のシステムフォントのフォールバックに依存します。
ほとんどの場合、swapを使用したいと思うでしょう
使用する値が分からない場合は、swapを使用してください。カスタムフォントとコンテンツのアクセシビリティのバランスが最適化されるだけでなく、JavaScriptに依存したのと同じフォントの読み込み動作が提供されます。
ページにフォントを読み込ませるけど、最終的に表示させたくない場合は、fallbackまたはoptionalがよいでしょう。
font-displayがサポートされていない場合
font-displayの唯一の懸念事項が、サポートブラウザが多くないことです。
それに対応するには、2つの選択肢があります。
- あなたは単にfont-displayを使うことができます。サポートされていないブラウザでは、提供するメリットは得られないだけです。これは何も壊さないという点で必ずしも悪いわけではありませんが、一瞬表示されないブラウザを使用しているユーザーが離れる可能性があります。
- font-displayがサポートされているか検出し、代替手段を提供することができます。時間とリソースが許せば、これがベストです。
font-displayがブラウザにサポートされているか検出するのは、簡単です。
1 2 3 |
if ("fontDisplay" in document.body.style === false) { /* JavaScript font loading logic goes here. */ } |
これは、完璧なフォールバックです。
あとは、Font Face Observerのようなサードパーティーのスクリプト、Firefox、Chrome、Operaで利用可能なネイティブのフォントロードAPIを利用するかを決めることができます。
1 2 3 4 5 6 7 8 |
if ("fontDisplay" in document.body.style === false) { if ("fonts" in document) { document.fonts.load("1em Open Sans Regular"); document.fonts.ready.then(function(fontFaceSet) { document.documentElement.className += " fonts-loaded"; } } } |
※より正確なクロスブラウザ対応にするには、コメントを参考にしてください。
ここでは通常のルートに進み、フォントロードAPIが移行を処理するようにします。
APIはフォントがロードされていることが分かると、<html>タグにfonts-loadedのクラスを適用します。このクラスを適用すると、カスタム書体の進行形のアプリケーションを可能にするCSSを書くことができます。
1 2 3 4 5 6 7 |
p { font-family: "Helvetica", "Arial", sans-serif; } .fonts-loaded p { font-family: "Open Sans Regular"; } |
わたし達はfont-displayのような短いCSSを使用して、これらが実現することを望んでいますが、必要に応じて別のソリューションでフォールバックする必要もあります。時間が経つにつれて、フォントロードAPIのようなソリューションは他のブラウザでも導入されることが予想されます。
サードパーティのフォントプロバイダについて
GoogleフォントやTypeKitなど、サードパーティのサービスを使ってフォントを埋め込むのであれば、することはあまりありません。font-displayプロパティは、@font-face宣言の内部で使用する必要があるからです。フォントプロバイダが提供するCSSは手を加えることができないため、font-displayプロパティを加えたり変更するができません。
しかし時間が経つにつれて、これらのプロバイダがfont-displayプロパティを含むCSSに変更したり、埋め込みコードのオプションとして許可する可能性があります。
いずれにしてもこのfont-displayプロパティは、Webタイポグラフィに歓迎されます。JavaScriptでは扱いにくい種類のタスクを大幅に簡素化できます。
sponsors