Catalina は、新しい統合可変システム フォントを macOS に導入しました。
CSS Fonts モジュール レベル 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 番太の太さが、その他に面白い微調整を加えた形で表示されます 👍?
遊び場
下の Glitch の [Remix to Edit] をクリックして Glitch の編集可能なコピーを入手し、新しい font-variation-settings
オプションを編集してフォントにどのように影響するかを確認します。この Glitch は macOS Catalina デバイスを使用している場合にのみ動作します。
macOS 10.15 ではシステム フォントに新機能が追加されています。macOS 10.15 では、Chromium バグトラッカーに system-ui
の厄介なバグが記録されていました。関連しているのではないでしょうか。
付録: system-ui
回帰
このストーリーは、別のバグ(#1005969)から始まります。この問題は macOS 10.15 で報告されています。system-ui
のフォントの間隔が狭く詰め込まれているためです。
バックグラウンド情報
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)は、サンフランシスコ向けの新しい統一可変フォントを出荷しました。[テキスト] と [ディスプレイ] を管理する必要がなくなります。また、前述の新しいバリエーション設定 opsz
も追加されました。
h1 {
font-variation-settings: 'opsz' 20;
}
残念ながら、新しい Catalina フォントのデフォルトの opsz
値は 20
であり、Chromium のエンジニアはシステム フォントに opsz
を適用する準備ができていませんでした。そのため、小さいサイズの表示が狭くなりすぎていました。
この問題を修正するには、opsz
をシステム フォントに正しく適用する必要がありました。この結果、問題 #1005969 は修正されました。勝利!それとも...
未完了
Chromium で opsz
が適用されましたが、正しく表示されませんでした。Mac のシステム フォントには、水平方向の間隔を調整する trak
というフォント テーブルが追加されています。Chromium のエンジニアは、この修正に取り組んでおり、macOS で CTFontRef
オブジェクトから水平方向の指標を取得する際に、trak
指標が指標の結果にすでに組み込まれていることに気づきました。Chromium のシェーピング ライブラリ HarfBuzz
には、trak
値がまだ考慮されていない指標が必要です。
内部的には、Skia(同じ名前の書体ではなくグラフィック ライブラリ)は、CoreGraphics
の CGFontRef
クラスと CoreText
の CTFontRef
クラスの両方を使用します。これらのオブジェクト間で必要な内部変換(下位互換性を維持し、両方のクラスで必要な API にアクセスするために使用)のため、Skia は特定の状況で体重の情報を失い、太字のフォントが機能しなくなります。この問題は問題 #1057654 で追跡されました。
Chromium が現在もサポートしているため、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 が重みの問題を検出しました。サイズ変更のための代替修正として、元の CTFont
から直接新しい CTFont
を作成し、CoreText
にドキュメント化されていない古い属性を使用して光学サイズを直接制御しました。これにより、10.11 での動作が維持され、その他の問題(光学サイズをデフォルト値に明示的に設定するなど)が修正されます。
ただし、この方法ではフォント内の CoreText
の「マジック」をより有効に活用することができます。そのうちの一つは、trak
テーブル(Chromium がすでにドキュメント化されていない属性を通じて抑制しようとしていたアプリケーション)以外のなんらかの方法で、グリフの進行を微調整していることのようです。
CGFont
はそのような「魔法」のいずれも行わないので、Chromium は CTFont
から CGFont
を取り除いて、それを使用して機能を強化できる可能性があります。残念ながら、CoreText
は他の方法でもフォントによって劣化することが報告されているため、この方法はうまくいきません。たとえば、小さな絵文字は、実際にリクエストしたよりも少し大きくなります(サイズを少し大きくします)。CGFont
はこれを認識していないため、スビックスベースの絵文字が互いに近すぎることになります。これは、1 つのサイズで測定しますが、CoreText
を使用すると、いくらか大きくなります。Chromium は CTFont
の進化を望んでいますが、トラッキングなしで、できれば他の面倒な機能がないことを望んでいます。
この間隔の問題を修正するには、相互接続された Blink と Skia の修正が必要だったため、Chromium のエンジニアは「単純に元に戻る」ことで問題を解決できませんでした。また、Chromium のエンジニアは Skia のフォント関連のコードパスを変更するために、別のビルドフラグの使用を試みました。これにより、太字のフォントの問題は修正されましたが、スペースの問題は解決しました。
解決方法
当然のことながら、Chromium はその両方を修正したいと考えていました。Chromium は、HarfBuzz に組み込まれたフォント OpenType フォント指標関数を使用して、システム フォントのフォント テーブルのバイナリデータから直接水平方向の指標を取得するようになりました。これを使用して、フォントに trak
テーブルがある場合、Chromium は CoreText
と Skia を回避します(絵文字フォントの場合を除く)。
それまでの間、Skia Issue #10123 が引き続きあり、Skia でのこの問題を完全に追跡し、HarfBuzz
で行われる現在の修正ではなく、Skia を使用してそこからシステム フォント指標を取得します。