問題
多くの場合、セレクタ + メディアクエリ、メディアクエリ + コンテナクエリなど、さまざまなタイプのフィルタ条件を組み合わせる必要があります。
たとえば、(prefers-color-scheme: dark) を、カラーパターンのオーバーライドをターゲットとするセレクタ(:root:has(> head > meta[name="color-scheme"][content="dark"]) や :root.dark など)と組み合わせると、カラーパターンの設定方法に関係なく、ライトモードまたはダークモードで特定のスタイルを適用できます。
単純なアプローチでは、コードが重複します。
/* Light mode styles */
.card.featured {
font-weight: 400;
}
#logo-dark {
display: none;
}
@media (prefers-color-scheme: dark) {
/* Dark mode styles */
:root:not(.light) {
.card.featured {
font-weight: 300;
}
#logo-dark {
display: inline;
}
#logo {
display: none;
}
}
}
/* Dark mode styles, again */
:root.dark {
.card.featured {
font-weight: 300;
}
#logo-dark {
display: inline;
}
#logo {
display: none;
}
}
代わりに行うこと
結合されたフィルタの結果をカスタム プロパティに保存し、コンテナ スタイルクエリを使用して、そのプロパティに基づいてルールを設定します。
重要: コンテナクエリの仕組み上、この手法は、一致する必要があるルールの祖先にカスタム プロパティを設定できる場合にのみ機能します。
1. 選択ロジックを適用されたルールから分離する
:root {
--color-scheme: light;
@media (prefers-color-scheme: dark) {
--color-scheme: dark;
}
&:has(> head > meta[name="color-scheme"][content="dark"]) {
--color-scheme: dark;
}
&:has(> head > meta[name="color-scheme"][content="light"]) {
--color-scheme: light;
}
}
2. 適用されたルールのカスタム プロパティのキー
@container not style(--color-scheme: dark) {
.card.featured {
font-weight: 400;
}
#logo-dark {
display: none;
}
}
@container style(--color-scheme: dark) {
.card.featured {
font-weight: 300;
}
#logo {
display: none;
}
}
3. 省略可: 表示を切り替えるためのユーティリティ クラス
非常に一般的なケースは、条件が一致するかどうかに基づいて表示を切り替えることです。ユーティリティ クラスは任意のコンポーネント スタイル(!important)よりも優先される必要があり、表示される display は不明であるため、オーバーライドを使用できません。not style(...) でゲートします。
@container not style(--color-scheme: dark) {
.if-dark {
display: none !important;
}
}
@container not style(--color-scheme: light) {
.if-light {
display: none !important;
}
}
フォールバック
フォールバックには、分岐の重要度と、許容されるフォールバックの内容に応じて、2 つの種類があります。
- スタイルクエリがサポートされていない場合でも、すべての状態が正しく機能する必要がある重要な分岐では、スタイルクエリを使用できません。代わりに、上記の単純なアプローチを使用して、各状態のルールを複製します。ユーティリティ クラスも、そのように定義されている限り、引き続き使用できます。
- デフォルトの状態が許容される、重要でない分岐の場合は、
@containerルールの外部で基本スタイルを定義し、スタイルクエリをオーバーライドとしてのみ使用できます。これにより、このアプローチの精神のほとんどが維持されます。主な欠点は、オーバーライドによって導入される値の結合です。
#logo-dark {
display: none;
}
@container style(--color-scheme: dark) {
#logo-dark {
display: inline; /* override */
}
#logo {
display: none;
}
}