font-feature-sttings
プロパティは便利だけど、値の意図しない上書きが発生しやすいという扱いづらさがある。たとえば「ページ全体でlocl
を有効にした上で、h1
要素ではpalt
を有効にしたい」というようなとき、以下のようなCSSを書いてしまいがちだ。
body {
font-feature-settings: "locl" 1;
}
h1 {
font-feature-settings: "palt" 1;
}
しかしこのときh1
のpalt
機能タグはbody
から継承されたlocl
機能タグに追加されるのではなく、これを上書きしてしまう。つまりh1
ではlocl
が無効になる。これは正しくは以下のように書かないといけない。
body {
font-feature-settings: "locl" 1;
}
h1 {
font-feature-settings: "locl" 1, "palt" 1;
}
このように、font-feature-settings
プロパティを指定するときはどのような値が継承されているかをつねに把握し、そこに値を「重ねて」指定する必要がある。機能タグが2つとか3つとかのうちはまだいいけど、ちょっと複雑なことをしようとすればすぐに管理しきれなくなるだろう。
こういった煩雑さを回避する方法として、ユニバーサルセレクターとカスタムプロパティ(CSS変数)を利用する方法を考えてみた。
*,
*::before,
*::after {
font-feature-settings:
"locl" var(--locl, 1),
"palt" var(--palt, 0);
}
h1 {
--palt: 1;
}
まずプロジェクトで利用しているすべての機能タグをユニバーサルセレクターで列挙し、デフォルトで有効か無効か(0
か1
、またはon
かoff
)をvar()
関数のフォールバック値として定義しておく。その上で機能タグを有効(または無効)にしたいセレクターでカスタムプロパティを指定する。こうすることで、カスタムプロパティを指定したセレクター以外ではフォールバック値が適用されることになる。注意すべきなのは、機能タグを追加するときに該当のセレクターだけではなくユニバーサルセレクターにもデフォルト値とともに追加しないといけないという点。
そもそもfont-feature-settings
プロパティは低レベルAPIであり、可能な限りfont-variant
系プロパティを利用することが推奨されている。こういった値の継承にともなう扱いの難しさを考えても、それが望ましい。しかし一方で、とくにCJKについてはfont-variant
系の仕様と実装が十分ではないという現状があり、font-feature-settings
に頼らざるを得ない場面は少なからずある。その利用には慎重になるべきという前提のもと、思わぬバグを生まないための工夫として、このカスタムプロパティを使う手法はそれなりに有効な気がする。