CSS Working Group の Editor's Drafts に見るCSSの未来

UI開発者 宇賀

皆さんこんにちは!最近CSS関連の話をよく耳にする気がするUI開発者の宇賀です。

先日社内でしていた雑談の中で、とあるCSS Working Groupのドラフトが話題になりました。

技術仕様の中で「Working Draft」という言葉をよく耳にすると思いますが、これはいわゆる「草案」のことで、W3Cの各ワーキンググループによって発行されます。今回タイトルにある「Editor's Draft」とは、そのさらに一歩手前のドキュメントで、文字通り仕様編集者たちの非公式な草案です。

今回は、Working DraftやEditor's Draftの中からいくつかの仕様をピックアップしてご紹介したいと思います。

Toggling Between Values: toggle()

CSS関数toggle()は CSS Values and Units Module Level 4 に含まれる仕様です。
https://www.w3.org/TR/css-values-4/#funcdef-toggle

この関数はとても興味深い振る舞いをします。同じセレクタに合致する要素は同じスタイルを継承しますが、toggle()を利用することでネスト回数に応じてプロパティの値を変化させることができます。

次の例だと、最初のem要素はitalicで、em要素の子孫のem要素はnormalになり、そのまた子孫のem要素はitalicになります。

/* CSS Values and Units Module Level 4 で紹介されている例 */
em {
  font-style: toggle(italic, normal);
}

ブラウザが元々実装しているプレーンなCSSだとli要素をネスティングするとビュレットの形が変わりますが、恐らくちょうどあの挙動が、1つの要素名のみをセレクタに持つ1つのルールセットで実現できるようになるということですね。

ただしこの仕様はat-riskに指定されているため、勧告案(PR)に進むまでの間に仕様が取り下げられてしまうかもしれないようです。現在のステータスはまだ草案(WD)なので、今後の動向に注目です。

Logical Combinations

これは Selectors Level 4 の仕様の中に含まれるものです。
https://www.w3.org/TR/selectors-4/#logical-combination

論理的な評価を実現する「Logical Combinations」にはすでに広くつかわれている:not()が含まれており、そのほかの疑似クラスもこの否定疑似クラスのように、引数で受け取ったセレクタリストに該当する要素をフィルタリングします。

この章では複数のCSSセレクタを1つにまとめて書くことができる:is()(かつて:matches()と呼ばれていた)や、セレクタの詳細度を0にする:where()などが定義されています。

中でも:has()は子孫から祖先を評価することができる疑似クラスで、個人的に1番注目している疑似クラスです!
いざというとき役立ちそうなので実装が楽しみですね!

/* Selectors Level 4 で紹介されている例 */
a:has(> img) {
  prop: value; /* 子要素にimg要素を持つa要素 */
}
dt:has(+ dt) {
  prop: value; /* dt要素の前にあるdt要素 */
}
section:not(:has(h1, h2, h3, h4, h5, h6)) {
  prop: value; /* ヘディングコンテンツを持たないsection要素 */
}
section:has(:not(h1, h2, h3, h4, h5, h6)) {
  prop: value; /* ヘディングコンテンツ以外を持つsection要素 */
}

セレクタではほかにも「Grid-Structural Selectors」など、カラムレイアウト用のセレクタが新たに定義されていたりします。ぱっと見は難解ですが、使えるようになればよりシンプルなマークアップで済むようになりそうでそちらも楽しみです!

Custom Media Queries

Media Queries Level 5 の仕様の中に含まれるものです。
https://drafts.csswg.org/mediaqueries-5/#custom-mq

現在は勧告候補(CR)になっているCSS Custom Propertiesでも、Sassのように共通の値をまとめられる仕様の策定が進んでいます。このCustom Media Queriesもその流れでしょうか。

Sassでは@mixinルールを使ったりして Media Query をまとめて記述したりしますが、近い将来ネイティブのCSSでもそのような感覚で記述することができるようになるかもしれませんね。

/* Media Queries Level 5 で紹介されている例 */
@custom-media --narrow-window (max-width: 30em);

@media (--narrow-window) {
  /* narrow window styles */
}
@media (--narrow-window) and (script) {
  /* special styles for when script is allowed */
}

CSS Nesting

そして最後はこちら、CSS Nestingです。

CSS Nesting Module Level 3 という名前でtabatkins氏によるEditor's Draftがまとめられています。
https://tabatkins.github.io/specs/css-nesting/

前述のMedia Query同様、Sassのような入れ子構造の記法をネイティブのCSSにも取り入れよう、という提案です。

/* CSS Nesting */
p {
  color:red;

  & span {
    color: white;
  }
}

/* 次のルールセットと等価です */
p {
  color: red;
}
p span {
  color: white;
}

Sassほどの自由さはないにせよ、ネイティブのCSSをこのように書くことができる時代はもうすぐそこまで来ているかもしれません。CSSワーキンググループは、このED(編集者草案)を受け入れて最初の草案(FPWD)の策定準備を進めているようです。

冒頭にある「話題になったドラフト」というのは実はこのCSS Nestingのことです。しばらくこの議論に目立った動きはありませんでしたが、先日この仕様をマージするプルリクエストに動きが見られたことをきっかけに少しCSS話に花が咲きました🌸笑
https://github.com/w3c/csswg-drafts/pull/2878

よく見ると、並行して「SCSS構文を取り入れてほしい」という提案もでているようですが果たしてこの先どうなるのでしょうか...。わくわくしますね...!

最後に

現存するさまざまな仕様も、始まりは誰かが持っていた1つのアイディアでした。

世の中には本記事でご紹介したもの以外にも、たくさんのドラフトがあふれています。

CSSに限らずそういった未実装の仕様、提案やリクエストから、世の中の開発者がどういった機能をどういう理由で欲しているのか、どういう問題が上がっていて他の開発者はどう反応しているのかを知ることでフロントエンドの未来を感じてみるのも、1つのWebの楽しみ方かもしれませんね。