Container style queriesでカスタムプロパティの値からスタイルを切り替える
Container style queriesは@container style()で祖先要素のカスタムプロパティの値を条件にスタイルを切り替えるCSSの仕組みです。Baseline 2026で揃ったので、テーマやコンテキストごとのスタイル分岐を子要素側で完結できるようになりました。
はじめに
Container queriesといえばサイズベースの@container (width > 600px)が定着していますが、もう一つの軸が@container style()関数を使ったスタイルクエリです。祖先要素のカスタムプロパティの値を条件にして、子要素のスタイルを切り替えられます。
Baseline 2026で揃ったContainer style queriesを使うと、親はカスタムプロパティを立てるだけで、子のCSSがそれを読んでスタイルを決める形に書けます。
基本構文
スタイルクエリは、まずcontainer-nameで祖先にスタイルクエリの対象として名前を付け、その親の上で評価したいカスタムプロパティを@container style(...)の中に書きます。
.theme {
container-name: theme;
スタイルクエリの対象にする親に名前を付ける
--theme: dark;
}
@container theme style(--theme: dark) {
theme と名前を付けた祖先の --theme が dark のときだけ当たる
.card {
background: black;
color: white;
}
}container-typeを指定する必要はありません。container-type: sizeやinline-sizeはサイズクエリ専用で、スタイルクエリは指定なしでもデフォルトで全要素が暗黙のスタイルクエリコンテナとして扱われます。サイズクエリのようなcontainmentの指定は不要です。
なお、@container theme { ... }のように条件を省略する書き方は、Chrome 148で追加されたname-only container queriesという別機能で、カスタムプロパティの値は見ません。スタイルクエリとして条件分岐したい場合はstyle()の中に条件を書きます。
サイズクエリとの違い
@container (width > 600px)のようなサイズクエリは、コンテナの寸法を条件にしてレイアウトを変えるのが目的です。スタイルクエリの目的はそれとは別で、親に立っている値(テーマ、サイズスケール、状態など)に追従して子のスタイルを変えることにあります。
条件として見るものも違います。サイズクエリはコンテナの幅や高さを見るので、親側にcontainer-type: inline-sizeなどのcontainment指定が必要です。スタイルクエリはコンテナのカスタムプロパティを見るだけなので、追加のcontainer-typeは必要ありません。
カスタムプロパティを使う
.surfaceに立てた--sizeの値に応じて、子孫の.buttonのパディングを切り替える例です。
.surface {
container-name: surface;
--size: md;
}
@container surface style(--size: md) {
.button {
padding: 8px 16px;
}
}
@container surface style(--size: sm) {
.button {
padding: 4px 8px;
}
}子コンポーネントにsize用のクラスを増やさずに、親側で--sizeを切り替えるだけでまとめて反映されます。
階層を超えて効かせる
カスタムプロパティはCSSの継承に乗るので、container-nameで祖先を固定しておけば、深い子孫からでも一番上の祖先を見に行けます。途中の要素が同じカスタムプロパティを上書きしていても、container-nameで対象を固定しておけば影響を受けません。
<section class="theme" style="--theme: dark">
<article style="--theme: light">
<p class="card">深い場所のカード</p>
</article>
</section>.theme {
container-name: theme;
}
@container theme style(--theme: dark) {
.card {
background: black;
color: white;
}
}@container themeはクエリの対象をcontainer-name: themeが付いている祖先に固定しているので、articleが--theme: lightに上書きしていても、sectionのdarkで判定されて.cardにはdark側のスタイルが当たります。
container-nameを付けずに@container style(--theme: dark)と書くと、対象はもっとも近い祖先のスタイルクエリコンテナになります。CSS Conditional Rules Module Level 5のcontainer-typeの定義で、スタイルクエリは「any element can be a query container」と明記されているので、もっとも近い祖先のスタイルクエリコンテナは実質的にスタイルを当てる要素の親要素です。上の例だとarticleの--theme: lightが見えて.cardにはdark側が当たりません。テーマやモードのような上から降ってくる文脈は、名前付きで明示しておくのが安全です。
Container style queriesで親のテーマに追従するカード
親の--csq-themeを切り替えると、子の.csq-cardのスタイルが@container style()で追従します。途中のラッパーは--csq-theme: lightに固定していますが、container-nameで対象を親に固定しているので、深い子孫のカードも親の値で判定されます。
親の--csq-themeの値
親 (--csq-theme: light)
直近の子のカード
親の値に応じて色が変わります。
途中のラッパーは--csq-theme: lightに固定
深い子孫のカード
途中で上書きされていても、container-nameで親に固定しているので親の値で判定されます。
おわりに
Container style queriesは、テーマやサイズスケールといった親の文脈に追従する子のスタイルを素直にCSSだけで書く道具です。Baseline 2026で主要ブラウザに揃ったので、子コンポーネントに対してテーマ用のクラスや属性を配って回る処理を減らし、子側のCSSが親の値を読みに行く形に書き直していけます。