font-paletteでカラーフォントを扱う
UI開発者 加藤先日、当社のPodcast「ミツエーテックラジオ」で公開した「#41『State Of CSS 2022から2023年のトレンドを占う』」でfont-palette
について少し取り上げました。
なかなか耳ではイメージしづらい内容だったため、今回は改めてカラーフォントとfont-palette
についてご紹介します。
従来のテキスト表現における課題
Webサイトにおいて文字の色を変えるにはCSSのcolor
プロパティを指定するのが一般的です。しかし、1つの文字が複数の色で形成されている場合はcolor
プロパティでは表現できません。
例えば文字の一部にアクセントとして違う色を使う場合や、3D表現をするために陰影を表現する場合があります。そのように見た目が少しリッチなテキスト表現をする場合は、テキスト画像を作ったり、canvas
要素によって処理することもあると思います。
テキスト画像は更新のコストが高く、数が増えてくると表示パフォーマンスにも影響がありますし、canvas
についてはJavaScriptで実装することになるため、実装のコストがかかってしまいます。
また、テキスト画像もcanvas
実装もプレーンテキストではなくなってしまうため、サイトを閲覧しているユーザーが拡大縮小、テキスト選択やコピーができないなど、アクセシビリティ、ユーザビリティを損ねてしまう可能性もあります。
カラーフォント
先にあげたような課題を改善する1つの手段がカラーフォントです。カラーフォントは簡単に言うと1つのグリフに複数の色情報を含んだフォントです。
Google Fontsでは「Show only color fonts」にチェックを入れると、Google Fontsで利用できるカラーフォントを検索できます。
カラーフォントを実現するにはOpenType-SVGやCOLRなどのフォントフォーマットに従ってフォントファイルを作成する必要があります。
中でもCOLRv1は比較的新しいフォーマットで、2023年1月現在ではSafari以外のモダンブラウザが対応しています。COLRv1では、COLRv0で実現できなかったグラデーションなどの仕様が追加されたり、フォント内部でシェイプデータを再利用することによってフォントファイル自体のファイルサイズが削減できるようになります。
※ なおCOLRv0はSafariでもすでにサポートされています。
font-paletteとfont-palette-value
カラーフォントの中には、複数の色パターンを含んでいるフォントも存在しています。例えばNablaは黄色をベースとしたパターン、ピンクをベースとしたパターンなど、計7つのパターンを提供しています。
そして、どのパターンを利用するのかを決めるCSSプロパティがfont-palette
、font-palette-value
の2つです。
font-palette
プロパティには、normal
、light
、dark
、<palette-identifier>
の4つの値が指定できます。
normal
はフォント側で指定されているデフォルトのパレットが適用され、light
、dark
の2つはフォントファイル側で指定されているライトモード、ダークモード用のパレットが適用されますが、フォントファイル側に指定がなければnormal
と同じパレットにフォールバックとして適用されます。
<palette-identifier>
にはfont-palette-value
を指定します。font-palette-value
は、アットルールの1つで、フォントのデフォルト値以外のパターンを使いたい時に使用します。
@font-palette-values --Nabla {
font-family: 'Nabla';
/* 3番目の色パターンを使う */
base-palette: 3;
}
p {
font-family: 'Nabla';
font-palette: --Nabla;
}
override-colors
font-palette-value
ではoverride-colorsによって部分的に色を変えることもできます。
@font-palette-values --Nabla {
font-family: 'Nabla';
/* 3番目の色パターンを使う */
base-palette: 3;
/* 3番目の色パターンに定義されている0から4番目の色を赤に変更する */
override-colors:
0 rgb(255, 0, 0),
1 rgb(255, 0, 0),
2 rgb(255, 0, 0),
3 rgb(255, 0, 0);
}
p {
font-family: 'Nabla';
font-palette: --Nabla;
}
注意点としてfont-palette-values
の中で、CSSカスタムプロパティの値を呼び出すことはできないようです。以下は動作しない例です。
:root {
--base-palette-index: 3;
}
@font-palette-values --Nabla {
font-family: 'Nabla';
base-palette: var(--base-palette-index);
}
現在の仕様には以下のような記載があります。
Functions such as calc(), var(), and env() are valid within the braces of a @font-palette-values rule. They are evaluated within the context of the root element. Relative units are also evaluated within the context of the root element.
しかし、執筆時点で試したところではCOLRv1をサポートしているGoogle Chrome、Firefox、Microsoft Edgeいずれも機能しませんでした。CSS Working GroupのGitHubには[css-fonts] [palettes] Disallow usage of var() in @font-palette-valuesというイシューも起票されています。
今後どうなるかは分かりませんが、現状で動的に切り替えたい場合はfont-palette-values
自体をカスタムプロパティに代入することで解決できます。
@font-palette-values --yellow {
font-family: 'Nabla';
base-palette: 0;
}
@font-palette-values --pink {
font-family: 'Nabla';
base-palette: 1;
}
:root {
--font-palette: --yellow;
}
p {
font-family: 'Nabla';
font-palette: var(--font-palette);
}
最後に、ここまで説明した内容をすべて盛り込んだ作例を掲載します。ぜひ試してみてください。
See the Pen font-paletteの例 by ミツエーリンクス (@mitsue-links) on CodePen.
まとめ
日本語に対応しているカラーフォントはまだ数少ないですが、検索してみるとひらがなやカタカナのみであれば対応しているものがいくつか見つかります。
色に依存した情報となってしまわないよう、アクセシビリティには十分配慮する必要がありますが、 今後、どんなフォントが出てくるのか楽しみですね。