CSS 条件付き規則 (CSS Conditional Rules) Level 5 仕様 (草案) に追加された @when と @else 規則について

つい先日、最初の草案が公開されたばかりですが、CSS 条件付き規則 (CSS Conditional Rules) の Level 5 仕様に、新たに加わった @when、および @else 条件付き規則について面白そうだったので簡単に紹介。

つい先日、最初の草案が公開されたばかりですが、CSS 条件付き規則 (CSS Conditional Rules) の Level 5 仕様に、新たに @when、および @else 条件付き規則が加わりました。

CSS の @ 規則 (アットルール) といえば、@charset@import@media、あるいは @keyframes など普段から CSS を書く人ならよく利用していると思いますが、このうち、いくつかの @ 規則は 「条件付き規則」 に分類され、この条件付き規則は論理値 (true / false) で条件を指定してそれぞれに当てはまる場合にのみ、条件付き規則の内部に記述されたスタイルを適用することができるほか、入れ子にして記述することで複雑な条件分岐も書けるようになっています。

現時点で多くのブラウザがサポートし、広く使われる条件付き規則としては @media 規則と @supports 規則がありますね。先に条件付き規則は 「入れ子」 にできますよと書きましたが、@media 規則を入れ子にできるって知らない人も結構いたりするんじゃないでしょうか (IE11 がサポートしていないので過去使いにくかったというのも大きいかもしれませんが)。

@media 規則の入れ子というのは例えば下記のように記述しても動作しますよということです。この例ならわざわざ入れ子にする必要はないと思いますけども。

@media screen {
  @media (min-width: 1280px) {
    /* ここにスタイル */
  }
}

@supports 規則もよく使いますよね。selector() 関数と組み合わせることで特定の CSS プロパティに対応している環境のみスタイルを適用したり、逆にしなかったりみたいなことが実現できます。

@supports (column-count: auto) {
    div {
        column-count: 3;
        column-width: 36em;
        column-gap: 2em;
    }
}

@supports 規則も条件付き規則ですから、@media 規則と入れ子にして記述するようなこともできます。

@supports (column-count: auto) {
    @media (min-width: 1600px) {
        div {
            column-count: 3;
            column-width: 36em;
            column-gap: 2em;
        }
    }
}

さて、ちょっと前置きが長くなってしまったのでそろそろ本題に入りますが、こういう条件付き規則を書くとき、当然考えるのは一般的なプログラミング言語、あるいは Sass のように、if とか else を使って書けたら楽じゃね? という話です。

例えば @supports 規則には notandor 演算子が使用できますし、@media 規則なら only 演算子があるので、それらを組み合わせることである程度の条件分岐は書けますけども、「ある条件にマッチしている場合は A で、それ以外は B」 みたいな条件を書こうとすると、下記のように 2 つの条件付き規則を併記することになり、冗長といえば冗長。

@media (min-width: 600px) {
  /* ここにビューポートの幅が 600px 以上だった場合のスタイル */
}
 
@media (max-width: 599px) {
  /* ここにビューポートの幅が 599px 以下だった場合のスタイル */
}

ここに、今回 「CSS Conditional Rules Module Level 5」 に追加された、@when、および @else 規則があると、どのように書けるかというと、下記のようになります。

@when media(min-width: 600px) {
  /* ここにビューポートの幅が 600px 以上だった場合のスタイル */
}
@else {
  /* ここに上記以外 (結果としてビューポートの幅が 599px 以下) だった場合のスタイル */
}

@when@else 規則それぞれの定義としては下記。

@when <boolean-condition> {
  <stylesheet>
}

@else <boolean-condition>? {
  <stylesheet>
}

<boolean-condition> には、media()、および supports() 関数。さらに拡張機能クエリとして font-tech()、および font-format() 関数を使用することができますが、media() 関数、supports() 関数に関しては、中身は @media 規則、@supports 規則そのままだと思ってもらえれば問題ないです。

ということで、仕様書のサンプルにもあるような、複雑な条件分岐も比較的直感的に書けるようになると。

@when media(width >= 400px) and media(pointer: fine) and supports(display: flex) {
  /* A */
} @else supports(caret-color: pink) and supports(background: double-rainbow()) {
  /* B */
} @else {
  /* C */
}

まだ最初の草案が公開されただけで、ブラウザのサポートがどうこうというレベルの話ではありませんからもしこのまま仕様策定が進んだとしてもまだまだ先の話だとは思いますが、面白い試みだなと思ったので紹介してみました。

ちなみに @when は元々 @if として議論が進んでいましたが、Sass と競合するんじゃね? ということで変更されたという経緯があります。

関連エントリー

記事をここまで御覧頂きありがとうございます。
この記事が気に入ったらサポートしてみませんか?