新春特別企画

2022年のCSS

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

:has()擬似クラスの実装

CSSで長らく望まれていたのが,親や祖先を選択するセレクタです。セレクタ仕様では:has()擬似クラスが以前から定義されていたのですが,クエリー対象となる要素が増え,パフォーマンスが悪化する懸念から,長年実装が行われていませんでした。

これが動いたのが昨年です。まず6月にChromiumでの実装がIgaliaにより始まりました。8月にはWebKitでも実装が始まり,昨年末リリースのSafari開発版で有効になりました。パフォーマンスの懸念についても,実装の工夫により抑えられているようです。すべてのブラウザとはいかないかもしれませんが,2022年に使えるブラウザが出てくることに期待したいです。

コンテナクエリーの実装も進む

レスポンシブなコードを書いているときに,画面幅ではなく,スタイルを適用するブロックの幅でスタイルを書き分けられたらと思うことはしばしばです。特にコンポーネントベースでUI部品をつくる昨今の開発においては,コンポーネント外の情報をなるべく考えずスタイルを書きたくなるため,メディアクエリーは筋が悪いとまで感じてしまうかもしれません。

こうした事情もあり,長年望まれてきた機能がコンテナクエリー(Container Queries)です。これはページ中のある要素をコンテナとして定義し,その幅に応じてスタイルを書き分けられる仕組みです。

/* コンテナの定義 */
main, .sidebar {
  container: inline-size;
}

/* デフォルトのカードスタイルは画像とテキストが縦に並ぶ */
.card {
  display: grid;
  grid-template:
    " image " auto
    "content" auto
    / 100% ;
}

/* コンテナの幅が400px以上の場合,画像とテキストを横並びに */
@container (width > 400px) {
  .card {
    grid-template:
      "image content" auto
      / auto 1fr ;
  }
}

記述したスタイルよっては,コンテナ要素とコンテナ内の要素が相互に参照しあうおそれもあります。これを回避するため,コンテナを定義した要素にはスタイルの封じ込め(containment)が行われます。封じ込めは,定義した要素の外に影響を及ぼさないと宣言することで,ブラウザにレンダリングの最適化余地を与える機能です。

コンテナクエリーは,封じ込めを定義するCSS Containment Level 3仕様で定義されています。将来的には幅だけでなく,スタイルやステートに応じたクエリーも書けることが提案されているなど,かなり夢のある仕様です。

実装ですが,Chromiumで2020年末から試験実装が始まっています。仕様の策定もまだ続いているので,早期にリリースされるわけではないでしょう。

ネスト,条件ブロック,スコープの仕様もドラフトが公開

CSSには様々な機能が求められています。要望の多くは,Sassや各種ライブラリ・ツールによって実現されてきた機能をCSSにも取り入れることです。そうした機能についても,仕様が公開され始めています。

構文の拡張で最も望まれているのが,ブロックのネストでしょう。これを実現するための仕様として,CSS Nesting仕様が提案され,昨年8月に最初のドラフトが公開されました。既存のCSSの構文との互換性から,Sassと全く同じ構文とはならなそうですが,導入されれば嬉しいと感じる方は多いでしょう。

メディアクエリーやフィーチャークエリーの拡張,そしてコンテナクエリーの登場により,複雑な条件をまとめる構文の需要も高まっています。昨年末に最初のドラフトが公開されたCSS Conditional Rules Level 5仕様では,@when@elseというルールが提案されています。

CSSの問題としてよく挙げられるスコープについても,CSS Cascading and Inheritance Level 6仕様で提案されており,昨年末に最初のドラフトが公開されました。提案されている@scopeルールを使うと,ある要素以下に対してのみスタイルを適用できるブロックを記述できます。また,要素ツリーの末端までではなく,ツリーの一部分にスコープを適用させることも検討されているようです。

これらはドラフトが出たばかりで,構文を含めまだまだこれからという状態です。すぐに実装され使えるというまでにはならないでしょうが,実現すればいまのCSSとは大きく異なるコードになりそうです。

CSSが大きく進み始めている

以上,CSSについて,今年サポートされそうな機能ほか,そう遠くないうちに来そうな機能,まだまだだけれど大きな変化を呼びそうな機能について紹介しました。

カスケードレイヤーのようにCSSの根幹に手を入れた機能が,もうすぐ使えるところまで来ています。渇望されてきた:has()擬似クラス,コンテナークエリーなども実装が始まっています。

絵に描いた餅だとずっと思っていたら,それがポンっと実体化してしまった。CSSにはそんな驚きが増えてきました。

実装が進んでいる機能は,効果的な使い方を探る段階に来ているのかもしれません。カスケードレイヤーは今後のCSS設計に大きな影響を与えるでしょうし,レイヤーのうまい切り分け方を考えはじめていくと良さそうです。

新しい機能は強力ですが,CSSの複雑さを高めることにもなります。:has()やコンテナクエリーなどは,よく考えて使わなければ,場当たり的で読みにくく管理性も悪いコードを生み出しかねません。今後は今よりもずっと,CSSの仕様や性質の理解が必要になっていくでしょう。

著者プロフィール

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

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

Twitter:@myakura