CSS で条件分岐を行う `@when/@else` ルール
`@when/@else` アットルールは条件付きスタイルをまとめて記述するためのルールです。`@media` や `@support` の条件を `@when` にわたすことで、`true` の場合には `@when` ブロック内のスタイルが、`false` の場合には `@else` ブロック内のスタイルが適用されます。このルールを使うことでより簡潔なコードを書くことができます。
@when/@else
アットルール 2024 年 6 月 22 日現在サポートされているブラウザはありません。実装状況については Can I use を参照してください。
CSS @when/@else
アットルールは @media
や @support
のような条件付き規則をまとめて記述するためのルールです。例えばメディアクエリを使って画面サイズが 640px 以上の場合には要素を表示し、それ以外の場合には非表示にするようなスタイルを記述する場合、以下のように記述できます。
@when media (min-width: 600px) {
.box {
display: block;
}
} @else {
.box {
display: none;
}
}
@when
ルールには boolean
を返す条件を記述し、条件が true
の場合にブロック内のスタイルを適用します。@else
ルールは条件が false
の場合には @else
ブロックのスタイルが適応されます。
@else
にさらに条件を追加することも可能です。
@when media (min-width: 640px) {
.box {
background-color: red;
}
} @else media(min-width: 768px) {
.box {
background-color: blue;
}
} @else {
.box {
background-color: green;
}
}
@when/@else
ルールは、@media
ルールや @support
ルールと同様に、スタイルの適用を条件に基づいて変更するためのルールです。@when
ルールには @media
ルールと同様にメディアクエリを記述できますが、@else
ルールはメディアクエリを記述することはできません。
この提案の初期段階では、@when
を使用するか @if
を使用するかについて議論がありました。@if
他の言語との一貫性があるものの、Sass などのプリプロセッサーですでに使用されており、既存のコードを壊す可能性があることから、@when
が採用されました。
@when/@else
ルールの使用例
相互に排他的なスタイルを適用する
@when/@else
ルールの使い所として、相互に排他的なスタイルを適用する場合があります。例えば prefers-reduced-motion
メディアクエリを使って、ユーザーが動きを減らす設定をしている場合にはアニメーションを非表示にしたい場合を考えてみましょう。@when/@else
を使わない場合、以下のように記述することになります。
.animation {
animation: slide-in 1s forwards;
}
@media (prefers-reduced-motion: reduce) {
.animation {
animation: none;
}
}
動きを減らす設定をしているかどうかは ON/OFF の 2 通りであり、両方の値を同時に取ることがない相互排他的な条件です。上記のコードは設定が ON の場合のスタイルをトップレベルに記述し、設定が OFF の場合のスタイルをメディアクエリ内に記述しています。この書き方はメディアクエリを使用する際によく見かけますが、以下の理由からコードが複雑になる恐れがあります。
- スタイルの記述順によってはスタイルが上書きされる可能性がある
- 2 つのコードの間に他のスタイルが挟まると、ON/OFF のそれぞれのスタイルが分散してしまい、コードの可読性が低下する恐れがある
1 つ目の問題点について詳しく見てみましょう。CSS の優先度のルールでは、同じ詳細度のセレクタが複数ある場合後に記述されたスタイルが優先されます。下記のように @media
ルールのスタイルを先に記述してしまうと、常に animation: slide-in 1s forwards;
で上書きされてしまうため、prefers-reduced-motion
メディアクエリのスタイルが適用されません。
@media (prefers-reduced-motion: reduce) {
.animation {
animation: none;
}
}
.animation {
animation: slide-in 1s forwards;
}
@when/@else
ルールを使えばこのように記述順を気にする必要がなくなります。
@when media (prefers-reduced-motion: reduce) {
.animation {
animation: none;
}
} @else {
.animation {
animation: slide-in 1s forwards;
}
}
複数の条件に基づくスタイルを記述する
複数の条件に同時に当てはまった場合のみスタイルを適用する場合に @when/@else
ルールを使うことで簡潔に記述できます。例えば画面幅が 1024px 以上かつ、grid
レイアウトがサポートされている場合に grid
レイアウトを適用する場合、以下のように記述していました。
@media (min-width: 1024px) {
@supports (display: grid) {
.container {
display: grid;
}
}
}
上記のように複数の条件を同時に満たす場合のスタイルを書きたい場合には、ブロックをネストする必要がありました。さらに条件が増えるとネストがどんどん深くなり、コードが複雑になる恐れがあります。@when/@else
ルールを使うと以下のよう and
で条件を結合して記述できます。
@when media (min-width: 1024px) and supports(display: grid) {
.container {
display: grid;
}
}
まとめ
@when/@else
ルールは条件付きスタイルをまとめて記述するためのルール@when
ルールには条件を記述し、条件がtrue
の場合にスタイルが適用される。@else
ルールは条件がfalse
の場合にスタイルが適用される。さらに@else
にも条件を追加することができる- できる相互に排他的にスタイルを適用する場合、
@when/@else
ルールを使うことでスタイルの記述順を気にする必要がなくなる - 複数の条件に基づくスタイルを記述する場合、
@when/@else
ルールを使うことでネストを減らし、コードを簡潔に記述できる