Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】Why My Fonts Caused Layout Shift: Field Notes on next/font, size-adjust, and Arabic Fallback Metrics

2026年10月15日に「Dev.to」が公開したITニュース「Why My Fonts Caused Layout Shift: Field Notes on next/font, size-adjust, and Arabic Fallback Metrics」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

ウェブフォントと代替フォントのサイズ・高さ不一致がレイアウトずれの原因。`next/font`はラテン文字のずれを自動修正するが、アラビア語など非ラテン文字は手動で`size-adjust`等のCSSを定義し、代替フォントの調整が必要だ。`font-display: optional`も有効。キャッシュを無効にして検証しよう。

ITニュース解説

Webサイトを開発していると、ページの読み込み時に文字が突然ずれたり、画像の位置が変わったりする現象に遭遇することがある。これは「レイアウトシフト」と呼ばれ、特にWebサイトの見た目の安定性を示す「Cumulative Layout Shift (CLS)」という指標に悪影響を与える。この記事では、フォントが原因で発生するレイアウトシフトのメカニズムと、それをどのように解決していくかを解説する。

レイアウトシフトは、フォントのダウンロード速度が遅いことだけが原因ではない。実は、ブラウザがWebフォントをダウンロードしている間に一時的に表示する「代替フォント(fallback font)」と、最終的に表示される「Webフォント」の見た目の特性、つまり「メトリクス」が一致しないことが根本的な原因だ。メトリクスとは、文字の幅、文字の高さ、行と行の間隔など、フォントの見た目を決めるさまざまな数字のことだ。

例えば、代替フォントがWebフォントよりも少し幅広だと、表示できる文字数が変わり、テキストが予期せず改行されてしまう。すると、そのテキストブロックの下にあるすべての要素がずれてしまう。同様に、代替フォントとWebフォントで行の高さが異なると、コンテンツ全体が縦方向に動いてしまう。このずれが、ユーザーに不快な体験を与え、CLSスコアを悪化させるのだ。たとえWebフォントの読み込みが速くなったとしても、コールドキャッシュ(初めてのアクセスなどでフォントが保存されていない状態)では、必ず一度は代替フォントが表示されるため、この問題は解決しない。

Next.jsというWebアプリケーションフレームワークを使っている場合、「next/font」という機能がフォントの管理を大いに助けてくれる。next/fontは、いくつかの重要な役割を果たす。まず、Webサイトで使うフォントファイルを開発サーバーから直接提供するように設定してくれる。これにより、フォントを外部のサービスから読み込む際のネットワークの遅延をなくせる。次に、各ページで必要なフォントを事前に読み込む「プリロード」という設定を自動で行うことで、フォントの表示を速くする。

さらに、next/fontの最も注目すべき機能の一つは、adjustFontFallback: trueという設定(これがデフォルトで有効になっている)によって、レイアウトシフトを自動的に防ぐための特別なCSSルールを生成することだ。このルールは、@font-faceというCSSの書き方を使って、代替フォントがWebフォントと同じ見た目になるように調整する。具体的には、size-adjust、ascent-override、descent-override、line-gap-overrideという四つの「CSS記述子」(フォントの見た目を細かく調整するための設定項目)を使って、代替フォントの文字の幅や行の高さといったメトリクスをWebフォントに合わせて調整するのだ。これにより、フォントがWebフォントに切り替わっても、見た目のずれが発生しなくなり、ユーザーは安定したページ表示を体験できる。Chrome、Firefox、Safariといった主要なブラウザは、これらの記述子をサポートしており、サポートしていない古いブラウザでは単に無視されるだけなので、互換性の心配は少ない。

しかし、next/fontのこの自動調整機能にも限界がある。next/fontが生成する調整済みの代替フォントは、基本的に英語などのラテン文字のシステムフォント(WindowsのArialやmacOSのTimes New Romanなど)に基づいて作られている。そのため、アラビア語、キリル文字、中国語、日本語、韓国語(CJK)といった非ラテン文字のフォントでは、残念ながらこの自動調整がうまく機能しない。これらの言語では、システムのデフォルトフォントのメトリクスがラテン文字とは大きく異なるため、依然としてレイアウトシフトが発生してしまうのだ。例えば、アラビア語のシステムフォントは、ラテン文字のフォントよりも行の高さが高くなる傾向があるため、ページ全体が縦にずれてしまうといった問題が起きる。

また、next/fontが提供するこの優れた機能も、誤った使い方をすると無効になってしまうことがある。next/fontは、生成した調整済みフォントをCSS変数(例えば--font-sans)として提供する。これをfont-family: var(--font-sans), system-ui, sans-serif;のようにCSS変数として使うべきなのだが、もし直接フォントファミリー名(font-family: Cairo, sans-serif;のように)を指定してしまうと、next/fontが生成した調整が適用されなくなり、レイアウトシフトが再び発生してしまうので注意が必要だ。

非ラテン文字のフォントでレイアウトシフトを解決するには、少し手間をかけて手動で調整済みの代替フォントを設定する必要がある。これは、まず使用するWebフォントと、その言語圏で一般的に使われるシステムフォント(例えば、アラビア語ならmacOSのGeeza ProやAndroidのNoto Naskh Arabicなど)のメトリクスを正確に把握することから始まる。これらのメトリクス情報(文字の平均幅、アセント、ディセント、ラインギャップなど)を元に、先ほど説明したsize-adjustなどのCSS記述子の値を自分で計算するのだ。そして、その計算結果を使って、@font-faceルールを手書きする。さらに重要なのは、この手書きのルールにunicode-rangeという記述子を追加することだ。これにより、その代替フォントがアラビア文字の範囲(U+0600-06FFなど)だけに適用されるように制限できる。こうすることで、例えば英語のテキストに誤ってアラビア語用の調整が適用されてしまうといった問題を避けられる。

フォントの表示方法には、font-displayというCSSプロパティがある。next/fontはデフォルトでfont-display: swapを設定している。これは、フォントがダウンロードされ次第すぐに代替フォントからWebフォントに切り替える方式だ。テキストがすぐに読めるようになるというメリットがある一方で、メトリクスが一致しない場合はレイアウトシフトが避けられないというデメリットもある。

もし、レイアウトシフトを絶対に避けたいのであれば、font-display: optionalという選択肢も検討すべきだ。optionalは、Webフォントが約100ミリ秒という短い時間内に読み込まれなかった場合、そのページの表示中は代替フォントを使い続け、Webフォントへの切り替えを一切行わない。Webフォントは、ユーザーが次に同じサイトを訪れたとき(その時にはWebフォントがキャッシュされているため)に表示されるようになる。この方式なら、フォントの切り替え自体が発生しないため、切り替えに起因するレイアウトシフトは完全に防ぐことができる。ただし、初めて訪れたユーザーは、意図したブランドフォントではなく、システムフォントでページを見る可能性があるというトレードオフがある。このため、本文テキストのように内容の可読性が重要な部分ではswapを使い、見出しなど見た目の印象が重要な部分でoptionalを使うなど、使い分けることが推奨される。

Webサイトのパフォーマンスを最適化する上で、フォントの「プリロード」も重要だ。next/font/googleは、あなたがCSSで指定したフォントの「サブセット」(例えばラテン文字だけ、アラビア文字だけなど)を、そのフォントが使われているページでしかプリロードしない。多言語サイトでは、英語のページでアラビア語のフォントまでプリロードしてしまうと、無駄なデータ転送が発生し、ページの読み込みが遅くなる可能性がある。これを避けるためには、各言語のセグメント(例えば/enや/arのようなURLパス)ごとにフォントのインポートを分ける工夫が有効だ。共有のレイアウトではラテン文字のフォントを読み込み、アラビア語のレイアウトではアラビア語のフォントを読み込む、といった具合だ。

最後に、レイアウトシフトが本当に解決されたのかを検証する方法も重要だ。開発中にテストしていると、一度読み込んだフォントはブラウザのキャッシュに保存されるため、レイアウトシフトが見えなくなることが多い。これを「ウォームキャッシュ」と呼ぶ。実際のユーザー環境では、初めて訪れる場合やキャッシュがクリアされた「コールドキャッシュ」の状態が頻繁に発生するため、この状態を再現してテストする必要がある。開発者ツールの「Disable cache」オプションを有効にし、ネットワーク速度を意図的に遅くする「スロットリング」機能を使ってテストすることで、実際のユーザーが経験するであろう状況を再現できる。

さらに、レイアウトシフトが発生しているかどうかを「目視」で確認するだけでなく、開発者ツールの「Performance」タブや、「Layout Instability API」というWeb標準の機能を使って、どの要素がどれだけ動いたのかを具体的な数値で確認できる。Chromeの開発者ツールには「Layout Shift Regions」という機能もあり、レイアウトシフトが発生した領域を視覚的にハイライトしてくれる。Lighthouseなどのツールでラボテストを行い、最終的には実際のユーザーからのデータ(Core Web Vitalsのフィールドデータなど)で効果を確認することが、確実な改善につながる。

next/fontは、特にラテン文字のフォントにおいては、レイアウトシフトの多くを自動で解決してくれる強力なツールだ。しかし、非ラテン文字の場合や、CSSの記述方法によっては手動での調整が必要となる。Webサイトの見た目の安定性を高め、ユーザーに快適な体験を提供するためには、フォントのメトリクス、font-displayプロパティの特性、そして正確な検証方法を理解し、適切に活用することが不可欠である。

関連コンテンツ

関連IT用語

関連ITニュース