CSS ネスティング(入れ子構文)
作成日:2024年月1日
CSS Nesting の概要
2023年12月の時点で、主なモダンブラウザでは、 CSS でも Sass のようにセレクターを入れ子にする構文が使えるようになっています(Sass と全く同じではありませんが、入れ子で記述できます)。
以下は MDN CSS 入れ子からの抜粋です。
CSS 入れ子 (CSS nesting) モジュールは、セレクターを入れ子にする構文を定義し、親ルールのセレクターに対して子ルールのセレクターを相対的に指定することで、あるスタイルルールを別のスタイルルールの中に入れ子にする機能を提供します
CSS 入れ子は、 Sass のような CSS プリプロセッサーとは異なり、 CSS プリプロセッサーによって事前にコンパイルされるのではなく、ブラウザーで解釈されます。
例えば、以下のような HTML がある場合、
従来は以下のように記述していた CSS を
以下のようにセレクタをネストして記述できるようになりました(入れ子の構文が使えます)。
リリース時のバージョンでは、要素タグ(要素名のセレクター)をネストするには、&(入れ子セレクター)を記述する必要がありましたが、現在は要素タグの入れ子でも & の記述は必要(必須)ではありません。
以下のように &(入れ子セレクター)を記述した場合は、上記と同じことになります。
以下は定義リストのスタイルに入れ子を使用した例です。
上記は以下と同じことです。
特定の場面(複合セレクターなどを使用してセレクターを互いに結合する場合など)では、入れ子セレクター &(Nesting Selector)が必要になることがあります。
サポート状況
サポート状況の詳細は以下で確認できます。
https://caniuse.com/css-nesting
Baseline は 2023 NEWLY AVAILABLE
と表示されていて、MDN では「2023年12月以降、この機能は最新のデバイスとブラウザーのバージョンで動作します。 この機能は、古いデバイスやブラウザでは動作しない可能性があります。」となっています。
古いブラウザへの対応
古いブラウザの対応が必要な場合は、以下のようなプラグインがあります。
入れ子セレクター(Nesting Selector)
入れ子を &
(入れ子セレクター)なしで記述した場合、自動的にセレクターの間に空白を追加した子孫セレクタとして解釈されます(空白は子孫結合子)。
上記の場合、.foo と .bar が空白で連結されて以下のように子孫セレクタとして解釈されます。
上記は、& を使って以下のように記述したのと同じことです( & と .bar の間に空白)。
& と .bar の間に空白がない場合は、異なって解釈されます。
上記は以下と同じことになります。
擬似クラスや複合セレクターでは & を直前に使用
例えば、以下のような HTML で .foo の文字色とホバー時の文字色を設定する場合、
以下のように &
を使わずに記述すると、
以下と同じことになり、.foo の子孫要素のホバー時の文字色の設定になり、リンク(.foo)にホバーしても色は変わりません。
この場合、例えば .foo に子要素(例えば span 要素)を追加して、その要素にホバーすれば、その要素の文字色がピンクになります(.foo *:hover
と解釈されるため)。
以下のように &
を使って記述すれば、.foo:hover
と解釈され、リンク(.foo)にホバーすると文字色が変わります。
上記は以下と同じことになります。
例えば、以下のような HTML で
以下のように入れ子にすると、4行目の &
はその親要素の .bar
を表し、7と8行目の &
はその親要素の & > a
、つまり .bar > a
を表すので
以下と同じことになります。
入れ子セレクターの追加
入れ子セレクターは任意のセレクタの後に追加することもできます。
以下のような HTML がある場合、
以下の CSS は
以下と同じことになります。
以下のように入れ子セレクターを後に追加することで、ルールのコンテキストを逆にすることもできます。
上記は以下と同じことになります。
以下のような HTML がある場合、
以下の & h2
(.foo h2
)にネストした .bar &
は .bar.foo h2
と解釈されます。
この場合、.bar &
は .bar
クラスを持つ要素内にある .foo h2
を指します(.bar
の子孫ではない)。
上記は以下と同じことになります。
また、入れ子セレクターは複数配置することができます。
入れ子セレクターは擬似要素を表わせない
入れ子セレクターは擬似要素を表すことはできません。
以下の CSS で入れ子セレクター &
は、.foo
にのみマッチします(疑似要素にはマッチしません)。
上記は以下と同じことです。
詳細度
複数の親要素がある(セレクターリストの)場合、入れ子セレクターの詳細度はその中で最大の詳細度を使用して計算されます。以下の HTML で、
以下の CSS を記述すると、上記の Text の色は blue になります。これは、親要素のリストに詳細度の高い id セレクター(#bar)があるためです。
入れ子セレクターの詳細度は、:is() 関数を使用した場合の詳細度の計算方法と同じになっています。
上記の場合、:is(#bar, div) p { color: blue; }
の方が.foo p { color: red;}
より詳細度が高くなり、color: blue が適用されます。
:where() を使って入れ子セレクターの詳細度を 0 にすることもできます。
以下の場合、.foo p の方が詳細度が高くなり、color: red が適用されます。
複数の親要素に対して :where() を使用しても詳細度を 0 にすることができるので、この例の場合、上記と同じ結果になります(.foo p の方が詳細度が高くなり、color: red が適用されます)。