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