つい先日、最初の草案が公開されたばかりですが、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
規則には not
、and
、or
演算子が使用できますし、@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 と競合するんじゃね? ということで変更されたという経緯があります。