概要
この記事では、フォントのフォールバックと、size-adjust
API、ascent-override
API、descent-override
API、line-gap-override
API について詳しく説明します。これらの API を使用すると、ローカル フォントを使用して、ウェブフォントのサイズにほぼ一致する、または完全に一致する代替フォント フェイスを作成できます。これにより、フォントの入れ替えによるレイアウト シフトが軽減またはなくなります。
この記事を読まなくても、これらの API をすぐに使い始めるためのツールをいくつかご紹介します。
フレームワーク ツール:
- @next/font: Next 13 以降、
next/font
は自動的にフォント指標のオーバーライドとsize-adjust
を使用して、それに対応するフォントの代替を提供します。 - @nuxtjs/fontaine: Nuxt 3 以降では、
nuxt/fontaine
を使用して、一致するフォントの代替を自動的に生成し、Nuxt アプリで使用されるスタイルシートに挿入できます。
フレームワーク以外のツール:
- Fontaine: Fontaine は、フォント指標のオーバーライドを使用するフォントの代替を自動的に生成して挿入するライブラリです。
- このリポジトリには、Google Fonts でホストされているすべてのフォントのフォント指標のオーバーライドが含まれています。これらの値は、コピーしてスタイルシートに貼り付けることができます。
背景
代替フォントとは、メインのフォント フェースがまだ読み込まれていない場合や、ページ コンテンツのレンダリングに必要なグリフがない場合に使用されるフォント フェースです。たとえば、以下の CSS は、"Roboto"
の代替フォントとして sans-serif
フォント ファミリーを使用する必要があることを示しています。
font-family: "Roboto" , sans-serif;
代替フォントを使用すると、テキストをより迅速にレンダリングできます(font-display: swap
を使用します)。その結果、ページ コンテンツがいち早く読みやすくなり、利便性も高まりました。しかし、これまでのところ、レイアウトが不安定になるという代償として、代替フォントがウェブフォントにスワップアウトされたときにレイアウト シフトが発生するのが一般的でした。ただし、以下で説明する新しい API では、対応するウェブフォントと同じスペースを占める代替フォント フェースを作成できるため、この問題を軽減または排除できます。
フォント フォールバックの改善
「改善された」目標を生み出すアプローチは 2 つ考えられます。サポートしています。より簡単なアプローチでは、フォント指標オーバーライド API のみを使用します。より複雑で強力なアプローチでは、フォント指標オーバーライド API と size-adjust
の両方を使用します。この記事では、この両方の方法について説明します。
フォント指標のオーバーライドの仕組み
はじめに
フォント指標のオーバーライドを使用すると、フォントの上昇、降下、ラインギャップをオーバーライドできます。
- Ascentは、フォントのグリフがベースラインから延長する最も遠い距離を示します。
- 下降は、フォントのグリフがベースラインより下に延びる最長距離を測定します。
- 行ギャップは「リーディング」とも呼ばれ、連続するテキスト行間の距離を示します。
フォント指標のオーバーライドを使用すると、代替フォントの上昇時、降下時、ラインギャップをオーバーライドして、ウェブフォントの上昇時、下降時、ラインギャップに合わせることができます。そのため、ウェブフォントと調整済みの代替フォントの縦方向の寸法は常に同じになります。
フォント指標のオーバーライドは、スタイルシートで次のように使用されます。
body {
font-family: Poppins, "fallback for poppins";
}
@font-face {
font-family: "fallback for poppins";
src: local("Times New Roman");
ascent-override: 105%;
descent-override: 35%;
line-gap-override: 10%;
}
この記事の冒頭で紹介したツールを使用すると、フォント指標のオーバーライドを正しく生成できます。ただし、これらの値を自分で計算することもできます。
フォント指標のオーバーライドの計算
次の式は、特定のウェブフォントのフォント指標をオーバーライドします。フォント指標のオーバーライドの値は、小数ではなくパーセンテージで記述する必要があります(例: 105%
)。
ascent-override = ascent/unitsPerEm
descent-override = descent/unitsPerEm
line-gap-override = line-gap/unitsPerEm
たとえば、Poppins フォントのフォント指標をオーバーライドすると次のようになります。
/*
Poppins font metrics:
ascent = 1050
descent = 350
line-gap = 100
UPM: 1000
*/
ascent-override: 105%; /* = 1050/1000 */
descent-override: 35%; /* = 350/1000 */
line-gap-override: 10%; /* = 100/1000 */
ascent
、descent
、line-gap
、unitsPerEm
の値はすべて、ウェブフォントのメタデータから取得されます。この記事の次のセクションでは、これらの値を取得する方法について説明します。
フォント テーブルの読み取り
フォントのメタデータ(具体的にはフォント テーブル)には、フォント指標のオーバーライドの計算に必要なすべての情報が含まれています。
<ph type="x-smartling-placeholder">フォントのメタデータを読み取る場合に使用できるツールをいくつか紹介します。
- fontkit は、Node.js 用に構築されたフォント エンジンです。こちらのコード スニペットは、fontkit を使用してフォント指標のオーバーライドを計算する方法を示しています。
- Capsize は、フォントのサイズ変更とレイアウトのライブラリです。Capsize は、さまざまなフォントの指標に関する情報を取得するための API を提供します。
- fontdrop.info は、フォント テーブルやその他のフォント関連の情報をブラウザから表示できるウェブサイトです。
- Font Forge は、よく使われているデスクトップ フォント エディタです。
ascent
、descent
、line-gap
を表示するには、Font Info
ダイアログを開いてOS/2
メニューを選択し、[Metrics
] タブを選択します。UPM
を表示するには、Font Info
ダイアログを開いて [General
] メニューを選択します。
フォント テーブルについて
「アセント」などの概念は複数の指標によって参照されます(たとえば、hheaAscent
、typoAscent
、winAscent
指標があります)。これは、オペレーティング システムが異なるフォント レンダリングに異なるアプローチをとっていることが原因です。OSX デバイスのプログラムは通常、hhea*
フォント指標を使用しますが、Windows デバイスのプログラムでは、一般的に typo*
フォント指標(sTypo*
とも呼ばれます)または win*
フォント指標を使用します。
フォント、ブラウザ、オペレーティング システムに応じて、フォントは hhea
、typo
、win
のいずれかの指標を使用してレンダリングされます。
Mac | Windows | |
クロム | 「hhea」の指標を使用表します | 「タイプミス」の指標を使用する「USE_TYPO_METRICS」の場合はテーブル設定されていない場合は、"win" の指標を使用します。表します |
Firefox | 「タイプミス」の指標を使用する「USE_TYPO_METRICS」の場合はテーブル設定されていない場合は、「hhea」の指標が使用されます。表します | 「タイプミス」の指標を使用する「USE_TYPO_METRICS」の場合はテーブル設定されていない場合は、"win" の指標を使用します。表します |
Safari | 「hhea」の指標を使用表します | 「タイプミス」の指標を使用する「USE_TYPO_METRICS」の場合はテーブル設定されていない場合は、"win" の指標を使用します。表します |
フォント指標がオペレーティング システム間でどのように機能するかについて詳しくは、業種別の指標に関するこちらの記事をご覧ください。
クロスデバイスへの対応
大部分のフォント(たとえば、Google Fonts でホストされているフォントの約 90%)では、ユーザーのオペレーティング システムを知らなくてもフォント指標のオーバーライドを安全に使用できます。つまり、これらのフォントでは、hhea
、typo
、win
の指標が適用されるかどうかにかかわらず、ascent-override
、descent-override
、linegap-override
の値がまったく同じになります。このリポジトリには、このリポが適用されるフォントと適用されないフォントに関する情報が提供されています。
OS X デバイスと Windows デバイスで別々のフォント指標オーバーライド セットを使用する必要があるフォントを使用している場合は、ユーザーのオペレーティング システムに基づいてスタイルシートを変更できる場合にのみ、フォント指標オーバーライドと size-adjust
を使用することをおすすめします。
フォント指標のオーバーライドの使用
フォント指標のオーバーライドは、代替フォントではなくウェブフォントのメタデータから取得された測定値を使用して計算されるため、代替フォントとしてどのフォントが使用されているかにかかわらず、オーバーライドは変わりません。例:
body {
font-family: "Poppins", "fallback for Poppins", "another fallback for Poppins";
}
@font-face {
font-family: "fallback for Poppins";
src: local("Arial");
ascent-override: 105%;
descent-override: 35%;
line-gap-override: 10%;
}
@font-face {
font-family: "another fallback for Poppins";
src: local("Roboto");
ascent-override: 105%;
descent-override: 35%;
line-gap-override: 10%;
}
サイズ調整の仕組み
はじめに
CSS 記述子 size-adjust
を使用すると、フォント グリフの幅と高さをそれに比例してスケーリングします。たとえば size-adjust: 200%
は、フォント グリフを元のサイズの 2 倍にスケーリングします。size-adjust: 50%
は、フォント グリフを元のサイズの半分にスケーリングします。
size-adjust
だけでも、フォントの代替機能を改善できる用途は限られています。ほとんどの場合、ウェブフォントに合わせるには、代替フォントを(比率でスケーリングするのではなく)若干狭くするか広げる必要があります。ただし、size-adjust
とフォント指標のオーバーライドを組み合わせることで、任意の 2 つのフォントを水平方向と垂直方向の両方で一致させることができます。
スタイルシートで size-adjust
は次のように使用されます。
@font-face {
font-family: "fallback for poppins";
src: local("Arial");
size-adjust: 60.85099821%;
ascent-override: 164.3358416%;
descent-override: 57.51754455%;
line-gap-override: 16.43358416%;
}
size-adjust
の計算方法(次のセクションで説明)により、size-adjust
の値(および対応するフォント指標のオーバーライド)は、使用する代替フォントに応じて変わります。
body {
font-family: "Poppins", "fallback for Poppins", "another fallback for Poppins";
}
@font-face {
font-family: poppins-fallback;
src: local("Arial");
size-adjust: 60.85099821%;
ascent-override: 164.3358416%;
descent-override: 57.51754455%;
line-gap-override: 16.43358416%;
}
@font-face {
font-family: poppins-fallback-android;
src: local("Roboto");
size-adjust: 55.5193474%:
ascent-override: 180.1173909%;
descent-override: 63.04108683%;
line-gap-override: 18.01173909%;
}
サイズ調整とフォント指標のオーバーライドの計算
size-adjust
とフォント指標のオーバーライドを計算するための式は次のとおりです。
size-adjust = avgCharacterWidth of web font / avgCharacterWidth of fallback font
ascent-override = web font ascent / (web font UPM * size-adjust)
descent-override = web font descent / (web font UPM * size-adjust)
line-gap-override = web font line-gap / (web font UPM * size-adjust)
これらの入力のほとんど(上昇、下降、ラインギャップ)は、ウェブフォントのメタデータから直接読み取ることができます。ただし、avgCharacterWidth
は近似する必要があります。
おおよその平均的な文字幅
一般に、平均文字幅は近似値ですが、正確に計算できるシナリオがあります。たとえば、等幅フォントを使用している場合や、テキスト文字列の内容が事前にわかっている場合などです。
avgCharacterWidth
を計算する単純なアプローチの例として、[a-z\s]
文字すべての平均幅を求めることがあります。
ただし、すべての文字を均等に重み付けすると、使用頻度の高い文字の幅(例: e
)が重み付けされ、使用頻度の低い文字の幅(例: z
)が重み付けされる可能性があります。
精度を向上させるより複雑なアプローチは、文字の出現頻度を考慮に入れて、[a-z\s]
文字の頻度加重平均幅を計算することです。英語のテキストの文字の出現頻度と平均的な単語長については、こちらの記事が参考になります。
アプローチを選択する
この記事で説明する 2 つのアプローチには、それぞれにメリットとデメリットがあります。
フォント フォールバックの最適化を始めたばかりの場合は、フォント指標のオーバーライドを単独で使用することをおすすめします。これは 2 つのアプローチのうち単純ですが、通常は、フォント関連のレイアウト シフトの大きさを顕著に小さくできるほど強力です。
一方、精度を高めたい場合や、もう少し作業やテストに前向きな場合は、
size-adjust
を組み込むのがよいでしょう。このアプローチを正しく実装すれば、フォント関連のレイアウト シフトを効果的に排除できます。
代替フォントを選択する
この記事で説明する手法は、ウェブフォントによく似たローカル フォントを探すのではなく、フォント指標のオーバーライドと size-adjust
を使用して、広く利用可能なローカル フォントを変換することに依存しています。ローカル フォントを選択する際は、ローカルに広く利用可能なフォントはほとんどありません。また、すべてのデバイスに 1 つのフォントが存在するわけではないことに注意してください。
Sans Serif フォントの代替フォントとして推奨されるのが Arial
で、Serif フォントの代替フォントとして Times New Roman
が推奨されています。ただし、これらのフォントはいずれも Android では利用できません(Roboto
は Android の唯一のシステム フォントです)。
次の例では、3 種類の代替フォントを使用してワイドスピード デバイスのカバレッジを確保しています。Windows/Mac デバイスをターゲットとする代替フォント、Android デバイスをターゲットとする代替フォント、汎用フォント ファミリーを使用する代替フォントです。
body {
font-family: "Poppins", poppins-fallback, poppins-fallback-android, sans-serif;
}
/*
Poppins font metrics:
- ascent = 1050
- descent = 350
- line-gap = 100
- UPM: 1000
AvgCharWidth:
- Poppins: 538.0103768
- Arial: 884.1438804
- Roboto: 969.0502537
*/
@font-face {
font-family: poppins-fallback;
src: local("Arial");
size-adjust: 60.85099821%;
ascent-override: 164.3358416%;
descent-override: 57.51754455%;
line-gap-override: 16.43358416%;
}
@font-face {
font-family: poppins-fallback-android;
src: local("Roboto");
size-adjust: 55.5193474%:
ascent-override: 180.1173909%;
descent-override: 63.04108683%;
line-gap-override: 18.01173909%;
}
フィードバックのお願い
フォント指標のオーバーライドと size-adjust
の使用についてご意見やご要望などございましたら、お気軽にお問い合わせください。