セレクタと @ ルールの組み合わせ

問題

多くの場合、セレクタ + メディアクエリ、メディアクエリ + コンテナクエリなど、さまざまなタイプのフィルタ条件を組み合わせる必要があります。

たとえば、(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 つの種類があります。

  1. スタイルクエリがサポートされていない場合でも、すべての状態が正しく機能する必要がある重要な分岐では、スタイルクエリを使用できません。代わりに、上記の単純なアプローチを使用して、各状態のルールを複製します。ユーティリティ クラスも、そのように定義されている限り、引き続き使用できます。
  2. デフォルトの状態が許容される、重要でない分岐の場合は、@container ルールの外部で基本スタイルを定義し、スタイルクエリをオーバーライドとしてのみ使用できます。これにより、このアプローチの精神のほとんどが維持されます。主な欠点は、オーバーライドによって導入される値の結合です。
#logo-dark {
  display: none;
}

@container style(--color-scheme: dark) {
  #logo-dark {
    display: inline; /* override */
  }

  #logo {
    display: none;
  }
}