こんにちは!フロントエンドの現場を長年歩んできたチーフアーキテクトの私です。
Webサイトを作っていて、「おしゃれなフォントを指定したのに、ページを開いた瞬間に文字が消えたり、別のフォントに変わったりして、ガタッとレイアウトが崩れる…」なんて現象に頭を悩ませたことはありませんか?「うわっ、またやっちゃったかな」と焦る瞬間ですよね。大丈夫です、あなただけじゃありません。世界中のエンジニアがこの「フォントの読み込み問題」と日々格闘しています。
今回は、Webブラウザの頭の中を覗き見しながら、このモヤモヤをスッキリ解消していきましょう。
—
Webブラウザはどうやって文字を表示している?
私たちが普段何気なく見ているWebページですが、ブラウザの裏側ではものすごいスピードで「オーケストレーション(大合奏)」が行われています。
HTMLが届くと、ブラウザはそれを上から順に解釈して「DOM(文書の構造)」を作ります。同時にCSSも読み込んで「CSSOM(見た目のルール)」を作ります。そして、この2つを合体させて画面に描き出す(レンダリングする)わけです。
ここで厄介なのが「Webフォント」です。
Webフォント(Google Fontsなど)は、サーバーの向こう側にある「フォントファイルの入った重たいダンボール箱」のようなものです。ブラウザは、ページを表示しようとしたときに、わざわざそのダンボール箱をネット経由で取りに行かなければなりません。
もし、ダンボール箱が届く前にブラウザが「さあ、文字を描くぞ!」と意気込んでしまったら……? ブラウザはパニックを起こします。この「届くまでの時間差」が、Web制作の現場でよく聞く FOIT や FOUT という現象を引き起こすのです。
—
2つの厄介者:FOITとFOUTの正体
フォントが読み込まれるまでの間に何が起きるのか、身近な例えでお話しますね。
1. FOIT(Flash of Invisible Text)=「透明人間文字の舞」
- どんな現象?:フォントが読み込まれるまでの数秒間、テキストが完全に消えてしまう現象です。画面が真っ白、あるいは「文字があるはずなのに何もない」状態になります。
- 例え話:役者が舞台袖で衣装に着替えている間、ステージの照明が完全に消されている状態です。「あれ、劇はじまらないの?」と観客が不安になりますよね。Safariなどのブラウザがよくこの挙動をします。
2. FOUT(Flash of Unstyled Text)=「とりあえず代役でGO!」
- どんな現象?:最初はスマホに入っている既存の標準フォント(メイリオやヒラギノなど)でパッと表示され、Webフォントのダンボール箱が届いた瞬間に、「お待たせしました!」と本来のフォントにパッと切り替わる現象です。
- 例え話:本物のアイドルが到着するまでの間、そっくりさんの「代役」がステージで踊っている状態です。本物が到着した瞬間にメンバーが入れ替わるので、画面がガタッと揺れる(レイアウトシフトが起きる)ことがあります。
「文字が消えるのも困るし、途中でフォントがガタッと変わるのもカッコ悪い……どうすればいいの?」
そんな私たちの願いを叶えるためにブラウザに指示を出せるのが、今回主役の `font-display` プロパティ です。
—
`font-display` でブラウザをコントロールしよう
CSSの `@font-face` ルールの中で `font-display` を指定してあげると、「フォントが届くまでの間、どう振る舞うべきか」をブラウザに優しく指示(命令)することができます。
代表的な4つのモードを、カフェの注文に例えて見てみましょう。
① `block` (カフェの「商品が届くまで席でお待ちください」モード)
- 挙動:フォントが届くまで、最大3秒間文字を隠します(FOIT)。3秒経っても届かない場合は、とりあえず標準フォントで表示します。
- こんな時に:どうしてもブランドの専用フォントを最初にピシッと見せたい場合。ただし、回線が遅い環境だと文字が消える時間が長くなるので注意が必要です。
② `swap` (カフェの「まずはお水をお出ししますね」モード)
- 挙動:最初から標準フォントを表示しておき(FOUT)、フォントが届き次第、すぐにWebフォントに置き換えます。
- こんな時に:「ユーザーを待たせたくない(テキストを早く読ませたい)」というニュースサイトやブログなど。実務で一番よく使われる、優しさあふれる設定です。
③ `fallback` (カフェの「少し待って来なかったら別のメニューにしますね」モード)
- 挙動:文字が約0.1秒ほど見えなくなり、すぐに標準フォントに切り替わります。もしフォントのダウンロードが間に合えばWebフォントになり、間に合わなければそのまま標準フォントで固定されます(途中で切り替わらない)。
- こんな時に:ページのレイアウトがガタッと変わるのを防ぎたいとき。
④ `optional` (カフェの「もうおまかせします!」モード)
- 挙動:ブラウザのネットワーク状況を見て、回線が速ければWebフォントを使い、遅ければ「もう標準フォントでいいや」とWebフォントのダウンロード自体を諦めます。
- こんな時に:通信量を節約したいスマホユーザー向けのサイトなど。
—
実務で使える!コピペOKのサンプルコード
それでは、実際のCSSコードを見てみましょう。
Google Fontsなどの外部フォントを使う際も、自前のローカルフォントを読み込む際も、基本の書き方はこうなります。
/ 自前のWebフォントをブラウザに優しく教える設定 /
@font-face {
/ フォントの名前(自分の好きな名前をつけられます) /
font-family: ‘MyOriginalFont’;
/ フォントファイルの場所を指定 /
src: url(‘/fonts/my-original-font.woff2’) format(‘woff2’);
/ 太字や斜体の設定 /
font-weight: 400;
font-style: normal;
/
【ここが今回のポイント!】
「swap」を指定することで、フォントが届くまでは標準フォントで即座に表示し、
準備ができたらスムーズにWebフォントへ切り替えます。
ユーザーを文字のない空白で待たせないための思いやり設定です。
/
font-display: swap;
}
/ 読み込んだフォントを実際に適用するクラス /
body {
font-family: ‘MyOriginalFont’, sans-serif;
/
万が一、Webフォントが読み込めなかったり失敗したときの保険として、
後ろに「sans-serif(一般的なゴシック体)」を必ず書いておきましょう。
/
}
—
チーフアーキテクトからのアドバイス
Webフォントの読み込み最適化は、ただ技術的なパフォーマンスを上げるだけではなく、「サイトを訪れてくれたユーザーに対するおもてなし」そのものです。
「表示速度が遅いから文字が消えている」という裏側のメカニズムを知っていれば、もうデザイン崩れや表示遅延に慌てることはありませんよね。`font-display: swap;` などを上手に使い分けて、ユーザービリティの高い、心地よいWebサイトを一緒に作っていきましょう!
もし実装で迷ったら、いつでもこの記事に戻ってきてくださいね。応援しています!

コメント