Catalina では、macOS に新しい統合可変システム フォントが導入されます。
CSS Fonts Module Level 4 仕様の 「system-ui」セクションでは、system-ui
フォント キーワードが定義されています。これにより、デベロッパーは、サイトやアプリで、組み込みの、ターボ最適化された、ローカライズされた、超高品質の、ダウンロード不要の、デフォルトのオペレーティング システム フォントを直接使用できます。
body {
font-family: system-ui;
}
このタイポグラフィの選択は、「このユーザーの現在のロケールのデフォルトのシステム フォントを使用する」と言うのと同等です。
macOS では、system-ui
フォントは San Francisco です。これは、デザインチームが精査、テストを行い、最近アップグレードしたフォントです。まず、Catalina の新しいエキサイティングなバリアブル フォント機能について説明し、次に、いくつかのバグと Chromium エンジニアがそれらを解決した方法について説明します。
この記事は、可変フォントについてすでに理解していることを前提としています。そうでない場合は、ウェブ上の可変フォント入門と以下の動画をご覧ください。
ブラウザの互換性
この記事の執筆時点では、system-ui
は Chromium(56 以降)、Edge(79 以降)、Safari(11 以降)、Firefox(43 以降、ただし -apple-system
キーワードを使用)でサポートされています。最新情報については、可変フォントを使用できますか?をご覧ください。
新しい力
Catalina でシステム フォントに導入された新機能が、Chromium 83 以降でウェブ デベロッパーに提供されるようになりました。system-ui
フォントにより多くの変数設定が追加されました。光学サイズと 2 つの独自のウェイト調整です。
h1 { font-family: system-ui; font-weight: 700; font-variation-settings: 'wght' 750 ; }
h1 { font-family: system-ui; font-weight: 700; font-variation-settings: 'wght' 750, 'opsz' 20, 'GRAD' 400, 'YAXS' 400 ; }
Mojave では、system-ui
は wght
設定のみの可変フォントです。Catalina の system-ui
は、wght
、opsz
、GRAD
、YAXS
の設定がある可変フォントです。
プログレッシブ エンハンスメントの設計機会がいくつかあるようです。必要に応じて、システム フォントの微妙な違いを詳しく調べてください。
wght
0
~900
の範囲のフォントの太さを指定します。すべての文字に同じ太さが適用されます。
/* 0-900 */
font-variation-settings: 'wght' 750;
opsz
光学サイジングはカーニングや文字間隔に似ていますが、間隔は数学ではなく人間の目で調整されます。19
以下の値はテキストと本文のコピーの間隔を調整するためのもので、20
以上の値はディスプレイ ヘッダーとタイトルの間隔を調整するためのものです。
/* 19 or 20 */
font-variation-settings: 'opsz' 20;
GRAD
ウェイトと似ていますが、水平方向のスペースには影響しません。400
~1000
の値を受け付けます。
/* 400-1000 */
font-variation-settings: 'GRAD' 500;
YAXS
グリフを縦方向に拡大します。400
~1000
の値を受け付けます。
/* 400-1000 */
font-variation-settings: 'YAXS' 500;
オプションの組み合わせ
数行の CSS を使用して、フォント設定を任意の太字に変更したり、他の興味深い組み合わせを試したりできます。
font-weight: 700;
font-weight: bold;
font-variation-settings: 'wght' 750, 'YAXS' 600, 'GRAD' 500, 'opsz' 20;
これで、macOS の Chromium ユーザーには、アップグレードされたカスタムの 750 ウェイトが他の楽しい調整とともに表示されます 👍
macOS 10.15 では、システム フォントに新機能が追加されました。また、macOS 10.15 では、Chromium バグトラッカーに system-ui
という厄介なバグが記録されました。関係があるのかな!?
付録: system-ui
回帰
このストーリーは別のバグ(#1005969)から始まります。これは、system-ui
フォントのスペーシングが狭く、詰まっているように見えるため、macOS 10.15 に対して報告されました。

背景
macOS 10.14 で、段落や見出しのフォントサイズを大きくしたり小さくしたりすると、フォントが別のものに「スナップ」されることに気づいたことはありませんか?
Mojave(macOS 10.14)では、system-ui
フォントはターゲットのフォントサイズに応じて 2 つのフォントを切り替えていました。テキストが 20px
の場合、macOS は「San Francisco Text」を使用していました。テキストが 20px
以上の場合は、macOS で「San Francisco Display」が使用されていました。光学サイズは、2 つの別々のフォントに静的に組み込まれていました。
Catalina(macOS 10.15)では、San Francisco の新しい統合可変フォントがリリースされました。「テキスト」と「ディスプレイ」の管理は不要になります。また、前述の新しいバリエーション設定 opsz
も追加されました。
h1 {
font-variation-settings: 'opsz' 20;
}
残念ながら、新しい Catalina フォントのデフォルトの opsz
値は 20
であり、Chromium エンジニアは opsz
をシステム フォントに適用する準備ができていませんでした。これにより、小さいサイズが狭く表示されていました。
この問題を解決するため、Chromium はシステム フォントに opsz
を正しく適用する必要がありました。これにより、問題 #1005969 が修正されました。勝利!それとも…?
未完了
ここで問題が発生しました。Chromium は opsz
を適用しましたが、まだ正しく表示されません。Mac のシステム フォントには、水平方向のスペーシングを調整する trak
という追加のフォント テーブルがあります。修正に取り組んでいる間、Chromium のエンジニアは、macOS で CTFontRef
オブジェクトから水平方向の指標を取得する際に、trak
指標がすでに指標の結果に反映されていることに気づきました。Chromium のシェーピング ライブラリ HarfBuzz
には、trak
値がまだ考慮されていない指標が必要です。

内部的には、Skia(同じ名前の書体ではなくグラフィック ライブラリ)は、CoreGraphics
の CGFontRef
クラスと CoreText
の CTFontRef
クラスの両方を使用します。これらのオブジェクト間の内部変換(下位互換性を維持し、両方のクラスで必要な API にアクセスするために使用)が必要なため、特定の状況で Skia の太さ情報が失われ、太字フォントが機能しなくなります。この問題は Issue #1057654 で追跡されていました。
Chromium が macOS 10.11 をサポートしているため、Skia は引き続き macOS 10.11 をサポートする必要があります。10.11 では、「San Francisco Text」と「San Francisco Display」のフォントは可変フォントではありませんでした。むしろ、利用可能なウェイトごとに個別のフォントのファミリーでした。ある時点で、グリフ ID が互いに同期しなくなりました。そのため、Skia が「San Francisco Text」でテキスト整形(描画可能なグリフへのテキストの変換)を行った場合、「San Francisco Display」で描画すると意味不明な文字になります。逆の場合も同様です。Skia が別のサイズを要求した場合でも、macOS が別のサイズに切り替える可能性があります。常にフォントの 1 つを使用して、それをスケーリングする(より大きなサイズを要求するのではなく、マトリックスを使用して拡大する)ことは可能ですが、CoreText
には、sbix(カラー絵文字)グリフを拡大しない(縮小のみ)という問題があります。実際はもう少し複雑です。CoreText
は、実際にはマトリックスの適用後に垂直方向の範囲を制限しているようです。これは、45 度の角度で絵文字を描画できないことに関連しているようです。いずれにしても、絵文字を大きく表示したい場合は、フォントのコピーを作成して大きなバージョンを取得する必要があります。
そこで、同じ基盤となるフォントデータが使用されるようにしながら、内部でさまざまなサイズの CTFont
オブジェクトのコピーを作成するために、Chromium は CTFont
から CGFont
を取り出し、CGFont
から新しい CTFont
を作成しました(CGFont
オブジェクトはサイズに依存しません。魔法のような切り替えは CoreText
レベルで行われます)。10.154 までは問題なく動作していました。10.15 では、このラウンド トリップで情報が失われすぎ、重み付けの問題が発生しました。Flutter は重みに関する問題に気づき、サイズ変更の代替修正が行われました。これにより、CoreText
の古いながらもドキュメント化されていない属性を使用して光学サイズを直接制御しながら、元の CTFont
から新しい CTFont
を直接作成できるようになりました。これにより、10.11 での動作が維持され、他の問題(光学サイズをデフォルト値に明示的に設定するなど)も修正されます。
ただし、これにより、フォントの CoreText
の「魔法」がより多く保持されます。その 1 つは、trak
テーブル(Chromium は別のドキュメント化されていない属性を使用してその適用をすでに抑制しようとしていた)だけでなく、何らかの方法でグリフの進みを調整しているように見えることです。
CGFont
はこのような「魔法」を一切行わないため、Chromium は CTFont
から CGFont
を取得して、それを進捗の取得にのみ使用できるかもしれません。残念ながら、CoreText
は他の方法でもフォントを操作することが知られているため、この方法は機能しません。たとえば、リクエストしたサイズよりも少し大きく絵文字を表示します(サイズを少し大きくします)。CGFont
はこのことを認識していないため、あるサイズで測定しても CoreText
がそれより少し大きく描画するため、sbix ベースの絵文字が互いに近くなりすぎます。Chromium は CTFont
の進歩を望んでいますが、トラッキングなしで、できれば他の混乱なしでそれを望んでいます。
スペーシングの問題の修正には、相互に関連する Blink と Skia の修正が必要だったため、Chromium エンジニアは「単に元に戻す」ことで問題を解決できませんでした。Chromium のエンジニアは、Skia のフォント関連のコードパスを変更するために別のビルドフラグを使用することも試しましたが、太字フォントの問題は解決したものの、スペーシングの問題が再発しました。
解決策
最終的に、Chromium は両方の問題を修正したいと考えました。Chromium は、システム フォントのフォント テーブルのバイナリデータから水平方向の指標を直接取得するために、HarfBuzz の組み込みフォント OpenType フォント指標関数を使用するようになりました。これにより、フォントに trak
テーブルがある場合、Chromium は CoreText
と Skia を回避します(絵文字フォントの場合を除く)。

それまでの間、Skia Issue #10123 で、Skia での完全な修正を追跡し、HarfBuzz
を介した現在の修正ではなく、Skia を使用してシステム フォントの指標を取得する処理に戻します。