新春特別企画

2022年のCSS

この記事を読むのに必要な時間:およそ 4 分

Safariが先行して実装する興味深い機能たち

ブラウザとウェブ標準の記事で取り上げましたが,2022年のSafariにはとても期待しています。エンジンの機能追加を伴うバージョンアップが頻繁に行われだしたからです。

なかでもCSSについては,面白い機能が技術プレビュー版ですでにいくつか実装されています。

まずは色関連です。LCH色空間など,より直感に近い色の指定ができる記法や,相対色を記述できる記法,色を混ぜ合わせるcolor-mix()関数などがCSS Colorモジュールに追加され,実装が進められています。Apple製品でDisplay P3など広色域のディスプレイが出てしばらく経ちますが,それらを活かしたいのでしょうか。

色の変換やアニメーションで複雑な計算を行いたいときに使うのでしょうか,sin()cos()tan()といった三角関数,ほかにもabs()round()などの数学関数も実装されています。ここまで要るのかという気もしますが,実装したとなると何かしらのユースケースがあるのでしょう。

ビューポートの大きさを元にした長さの単位,vwvhにも機能追加があります。モバイルではアドレスバーの表示状態でビューポートの大きさが変わってしまうことがあり,画面いっぱいに要素を広げるスタイルに難がありました。

それに対応するべく,ビューポートの最小時や最大時,動的に変化するビューポートを参照する単位,svw/svhlvw/lvhdvw/dvhなどが仕様に追加され,実装されています。

また,2021年はMacBook Proがモデルチェンジを行い,ProMotionという可変フレームレート技術を採用したディスプレイがMacに初搭載されました。スクロールやアニメーションなどがよりヌルヌルと動く期待が持てます。

しかし現在アニメーションの実装でよく使われているrequestAnimationFrame()に対し,そのまま可変フレームレートを適用してしまうと,バッテリー消費が上がる,一部サイトのアニメーションに影響が出てしまうといった問題があるようです。可変フレームレートでのアニメーションをよくすべく,AppleはWeb Animations仕様の拡張を提案しています。

ハードウェアの機能を活かしたプラットフォーム機能の提案は,Appleの垂直統合モデルならではのものと感じます。表現力の向上に寄与する提案を,今後も期待したいです。

カスケードレイヤーが全ブラウザでサポート

ここからが冒頭で言及した,CSS根幹を拡充する機能の紹介です。

CSSにはカスケーディングという,数あるスタイル宣言(プロパティと値のペア)から,どの値を使うかを解決する仕組みがあります。CSSのCはカスケーディング(cascading)からきており,CSSの根幹をなすものです。

カスケーディングでは,宣言の登場順(order of appearance)や,セレクタの詳細度(specificity)などいくつかの優先順位から,最終的に使われる宣言が決定されます。 詳細はMDNの記事などを読んでいただくとして,簡単に述べると,セレクタの詳細度が高いものが優先され,詳細度が同じ場合は登場順が後のものが優先されるようになっています。

CSSを書く際は,セレクタの詳細度や登場順を気にしてスタイル宣言を書いていくわけですが,サイトやアプリが大規模になればなるほど,現在のシンプルなカスケーディングでは立ち行かなくなります。サードパーティのコードのCSSによって,意図せず宣言が奪われることもあります。詳細度を下げコントロールを行いやすくするBEMなどの命名規約も発明されましたが,本質的な解決ではありませんでした。

そこに登場したのが,CSS Cascading and Inheritance Level 5仕様で提案された,カスケードレイヤー(Cascade Layers)です。セレクタの詳細度よりも優先されるレイヤー(layers)という概念を導入し,宣言の優先順位をコントロールしやすくする仕組みです。

レイヤーの優先度を工夫すると,たとえばIDセレクタをclassセレクタで上書きできるようになります。

/* <div id="A" class="B C"> という要素があったとして */
div { height: 100px }

@layer one {
  /* このレイヤーを見る限りは red になりそうだが */
  #A { background-color: red }
  .B { background-color: blue }
}
@layer two {
  /* このレイヤーのほうが優先度が高いので,green になる */
  .C { background-color: green }
}

またレイヤーは入れ子にしたり,優先度を別のところで定義できるなど,優先度の制御に自由が効くようになっています。とりあえず後ろにスタイルを書いていくといったことを,しなくてもよくなるのです。

/* レイヤーの優先度はあらかじめ定義できる */
@layer reset, base, components, util;

/* resetレイヤーにnormalize.cssをインポート */
@import url(normalize.css) layer(reset);

@layer util {
  /* utilレイヤー */
}
@layer base {
  /* baseレイヤー。一番後なので他のレイヤーよりも優先度が高そうだが,
     最初の@layerルールで優先度が決まっているので,utilのほうが優先される */
}

ほかにもいろいろな例がMDNの記事にありますので,読んでみてください。

カスケードレイヤーはかなり強力で,カスケーディングという根幹に触る機能なので,この仕様が提案された時に筆者は「かなりの時間がかかるだろうな」と思っていました。しかし2021年の半ばから各ブラウザで実装が始まり,年末にはリリース直前という段階まで達しました。Firefoxでは2月リリースのFirefox 97,Chromeでは3月リリースのChrome 99でリリース予定です。Safariでも開発版で有効になっており,遠くない時期にリリースされるでしょう。

仕様の提案が出てきたのが2019年の半ばだったので,2年で基本的な仕様の策定と,さらには実装も行われたことになります。驚くべき早さです。

著者プロフィール

矢倉眞隆(やくらまさたか)

HTMLやCSSといったW3C/WHATWGのウェブ標準仕様やブラウザーのエンジンについて,20年ほどなんとなく追いかけている。現在は株式会社ピクセルグリッドに所属。

Twitter:@myakura