Webフォントとブラウザーのフォント選択

最終更新: 2024-09-03 19:44:16 +0800 +0800
tags: Css | Fonts | Performance | Web
原文は英語で書かれています。あなたはAI翻訳版を読んでいます。

書体、またはフォントファミリーは、関連するフェイスをまとめたものです。フェイスには、ウェイト、スタイル、ストレッチなどのプロパティがあります。グリフは、文字または文字列に対して選択され、描画される形状です。

ブラウザーによるフォント選択は、文字ごとに行われます。そのため、段落内でラテン文字にはあるファミリー、CJK文字には別のファミリー、絵文字には絵文字フォントを使用できます。

フォントファミリーのスタックを構築する #

font-family は、ファミリー名と総称ファミリー名の順序付きリストです。

css
body {
  font-family:
    "Example Sans",
    "Noto Sans",
    system-ui,
    sans-serif;
}

空白を含むファミリー名は引用符で囲みます。オペレーティングシステムによってローカルフォントの可用性が異なるため、スタックの末尾には総称ファミリー名を指定します。

総称ファミリーには、serif、sans-serif、monospace、cursive、fantasy、system-ui、ui-serif、ui-sans-serif、ui-monospace、ui-rounded、emoji、math、fangsong があります。新しい総称名への対応状況は異なるため、最後には幅広いフォールバックを残してください。

ブラウザーは各文字について、利用可能なフェイス、要求されたスタイル、ウェイト、ストレッチを検討し、選択したフェイスにグリフがない場合はフォールバックします。フォールバックによって、1行内でメトリクスが変わることがあります。実際のコンテンツに含まれるスクリプトをテストしてください。

ダウンロード可能なフェイスを宣言する #

@font-face は、ファミリーとフェイスの範囲をリソースに関連付けます。

css
@font-face {
  font-family: "Example Sans";
  src: url("/fonts/example-sans-latin.woff2") format("woff2");
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
}

この宣言だけではフォントは適用されません。後続の font-family 宣言によって選択されます。

ファイルに対応する可変軸が含まれていない限り、イタリック体と正立体は別々に宣言します。

css
@font-face {
  font-family: "Example Sans";
  src: url("/fonts/example-sans-italic.woff2") format("woff2");
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
}

正確なディスクリプターを指定すると、実際のフェイスが存在する場合にブラウザーが太字やイタリック体を合成するのを防げます。

合成された太字、イタリック体、スモールキャップがデザインに反し、必要なすべてのフェイスを利用できる場合に限り、font-synthesis: none を設定します。それ以外の場合、選択されたフォントに要求されたフェイスがないとき、合成によって強調表示を維持できます。

Webフォント形式を理解する #

最新のサイトでは WOFF2 を優先してください。WOFF2 は、Web配信用に設計された圧縮を用いて OpenType または TrueType のフォントデータを格納します。

FormatRole
TrueType (.ttf)TrueTypeアウトラインを使用するデスクトップおよびプラットフォーム向けフォント形式
OpenType (.otf)複数のアウトライン技術とレイアウト技術に対応するフォントコンテナー
WOFF圧縮とメタデータを備えたWebコンテナー
WOFF2より強い圧縮を備えた新しいWebコンテナー
EOTInternet Explorer向けの歴史的なWeb形式
SVG fonts廃止されたテキストフォント機構。SVGはアイコンやグラフィックには引き続き有用

形式を変換しても、再配布権が付与されるわけではありません。セルフホスティングまたはサブセット化の前に、フォントのライセンスを確認してください。

可変フォントを意図的に使用する #

可変フォントは、1つのファイルに複数のデザイン範囲を格納します。登録済みの軸には、ウェイト(wght)、幅(wdth)、オプティカルサイズ(opsz)、スラント(slnt)、イタリック(ital)があります。

css
@font-face {
  font-family: "Example Variable";
  src: url("/fonts/example-variable.woff2") format("woff2");
  font-weight: 300 800;
  font-stretch: 75% 125%;
  font-style: normal;
}

登録済みの軸には、font-weight や font-stretch などの高レベルプロパティを使用します。font-variation-settings は、カスタム軸や正確な低レベル制御に適しています。

可変フェイスは、静的フェイスと同じファミリーマッチングアルゴリズムに参加します。宣言された軸の範囲内の要求では、補間されたインスタンスが選択されます。要求が範囲外の場合、マッチングでは最も近いサポート値、またはファミリー内の別のより適合するフェイスが使用されます。選択されたフェイスに文字がない場合、その文字についてフォールバックファミリーリストを通じた選択が続行されます。ブラウザーが要求されたインスタンスを生成できないフェイスを選択しないよう、正確な範囲を宣言してください。

可変ファイルは、すべての静的フォントセットより自動的に小さくなるわけではありません。表現される範囲を十分にページで使用し、追加の可変データを相殺できる場合に効率的です。

読み込みとレイアウトシフトを制御する #

font-display はフォールバックの動作を定義します。

  • block は、フォールバック前に短時間の不可視テキスト期間を許可します。
  • swap はフォールバックを直ちに表示し、フェイスの到着時に置き換えます。
  • fallback は短いブロック期間と限定的なスワップ期間を使用します。
  • optional は、制約された状況ではブラウザーがフォールバックを維持することを許可します。

swap は読みやすいテキストを維持しますが、メトリクスの不一致によってレイアウトが移動することがあります。比率の近いフォールバックを選ぶか、メトリクスのオーバーライドを使用します。

css
@font-face {
  font-family: "Example Sans Fallback";
  src: local("Arial");
  size-adjust: 102%;
  ascent-override: 92%;
  descent-override: 24%;
  line-gap-override: 0%;
}

オーバーライド値は推測ではなく、測定したフォントメトリクスから導出してください。

初期レンダリング中に必要なフェイスだけをプリロードします。

html
<link
  rel="preload"
  href="/fonts/example-sans-latin.woff2"
  as="font"
  type="font/woff2"
  crossorigin>

プリロードURL、CORSモード、@font-face URLが一致しない場合、ブラウザーがリソースを2回ダウンロードする可能性があります。過剰なプリロードは、重要なCSS、スクリプト、画像と競合します。

文字カバレッジでサブセット化する #

unicode-range を使用すると、テキストが対象のコードポイントを必要とする場合にのみ、ブラウザーがフェイスをダウンロードします。

css
@font-face {
  font-family: "Example Sans";
  src: url("/fonts/example-sans-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153;
}

サブセット全体で、結合文字、句読点、記号、サポートするすべての言語をカバーする必要があります。結合文字が欠落すると、基底文字と整列しないフォールバックグリフが生成されることがあります。

ローカルフォントへのアクセス #

window.queryLocalFonts() は、対応ブラウザーでユーザーの許可を得た後、ローカルにインストールされたフォントを列挙できます。

js
const fonts = await window.queryLocalFonts();
const matching = fonts.filter((font) => font.family === "Noto Sans");

フォントの列挙は識別情報を公開するため、厳格な権限および可用性の制約があります。通常のページレンダリングをこれに依存させないでください。CSSのフォントマッチングは、ファミリースタックに記載されたインストール済みフォントをすでに使用しています。

@font-face の local() ソースも、インストール済みフォントの可用性をCSSマッチングに公開します。プライバシー保護のため、ブラウザーはローカルソースを無視したり、その精度を下げたりすることがあります。そのため、ローカルヒントの後にダウンロード可能なソースを指定してください。

css
@font-face {
  font-family: "Example Sans";
  src:
    local("Example Sans"),
    url("/fonts/example-sans.woff2") format("woff2");
}

フィンガープリンティングの仕組みとして、ローカルフォントのプローブを長いリストで使用しないでください。

コメント

GitHub で閲覧・コメントする(投稿にはログインが必要です)