CSS ネスティング モジュール レベル 1

W3C 作業草案,

この文書の詳細
この版:
https://www.w3.org/TR/2026/WD-css-nesting-1-20260122/
最新の公開版:
https://www.w3.org/TR/css-nesting-1/
編集者草案:
https://drafts.csswg.org/css-nesting/
履歴:
https://www.w3.org/standards/history/css-nesting-1/
フィードバック:
CSSWG Issue リポジトリ
仕様内インライン
編集者:
Tab Atkins-Bittner (Google)
前編集者:
Adam Argyle (Google)
この仕様への編集提案:
GitHub 編集者
テストスイート:
https://wpt.fyi/results/css/css-nesting/

概要

このモジュールでは、1つのスタイルルールを別のルールの内部にネストする機能を導入します。子ルールのセレクターは親ルールのセレクターに対して相対的です。これにより、CSSスタイルシートのモジュール性と保守性が向上します。

CSSは、HTMLやXMLなどの構造化文書のレンダリングを画面上や紙上などで記述するための言語です。

この文書のステータス

このセクションでは、文書公開時点でのステータスについて説明します。 現在のW3C公開文書の一覧およびこの技術報告書の最新改訂版は W3C 標準および草案インデックスに掲載されています。

この文書は、CSS ワーキンググループによって 作業草案 (Working Draft) として 勧告トラックを使用して公開されました。 作業草案としての公開は、W3Cおよびそのメンバーによる承認を意味するものではありません。

これは草案文書であり、随時更新、置換、または他の文書により廃止される可能性があります。 進行中の作業以外の文書として引用することは不適切です。

フィードバックは、GitHubでのIssue提出(推奨)により送信してください。 タイトルに仕様コード「css-nesting」を含めてください: 「[css-nesting] …コメントの概要…」。 すべてのIssueやコメントはアーカイブされています。 または、(アーカイブ済み) 公開メーリングリスト www-style@w3.org でもフィードバックを送ることができます。

この文書は 2025年8月18日 W3C プロセス文書 に基づき運用されています。

この文書は、W3C 特許ポリシーの下で運営されるグループにより作成されました。 W3Cは、グループの成果物に関連して行われた特許開示の公開リストを維持しています。 このページには特許開示の手順も含まれています。 実際に特許を知っており、その特許が本質的請求項 (Essential Claim)を含むと考える個人は、 W3C特許ポリシー第6節に従って情報を開示する必要があります。

1. 導入

この節は規範的ではありません。

このモジュールは、あるスタイル規則の内部に別のスタイル規則をネストすることをサポートする方法を説明します。内側の規則のセレクタは外側の規則で一致した要素を参照できるようになります。この機能により、関連するスタイルを CSS 文書内の単一の構造にまとめることができ、可読性と保守性が向上します。

テスト

ネストの一般的なテスト


1.1. モジュールの相互作用

このモジュールは [CSS21] パーサモデルを拡張する新しいパーサ規則を導入します。
また [SELECTORS-4] モジュールを拡張するセレクタを導入します。
さらに [CSSOM-1] モジュールで定義されたいくつかの IDL とアルゴリズムを拡張・変更します。

1.2.

この仕様は新しいプロパティや値を定義しません。

2. 解説

この節は非規範的です。

よりコンパクトに書きたい CSS があると想像してください。

.foo {
  color: green;
}
.foo .bar {
  font-size: 1.4rem;
}

ネストを使うと、このように書けます:

.foo {
  color: green;
  .bar {
    font-size: 1.4rem;
  }
}

Sass や他の CSS プリプロセッサでスタイルをネストしてきたなら、とても馴染みがあるでしょう。

親のスタイル規則の内部に任意の規則をネストできます:

main {
  div { ... }
  .bar { ... }
  #baz { ...}
  :has(p) { ... }
  ::backdrop { ... }
  [lang|="zh"] { ... }
  * { ... }
}

デフォルトでは、子規則のセレクタは親規則に対して子孫結合子で接続されるものとみなされますが、ネストされたセレクタを任意の結合子で始めてその接続方法を変更することができます:

main {
  + article { ... }
  > p { ... }
  ~ main { ... }
}

新しい & セレクタは親のセレクタで一致した要素を明示的に参照することを可能にします。したがって、前の例は次のようにも書けます:

main {
  & + article { ... }
  & > p { ... }
  & ~ main { ... }
}

しかし、ネストされたセレクタ内で & を他の位置に置くことで、親と子の規則の間の別の種類の関係を示すこともできます。例えば、次の CSS:

ul {
  padding-left: 1em;
}
.component ul {
  padding-left: 0;
}

はネストを使って次のように書き換えられます:

ul {
  padding-left: 1em;
  .component & {
    padding-left: 0;
  }
}

再び、& は「ネストされたセレクタをここに置きたい」ということを示す方法を提供します。

セレクタ同士の間にスペースを入れたくない場合にも便利です。例えば:

a {
  color: blue;
  &:hover {
    color: lightblue;
  }
}

このようなコードは a:hover { と同じ結果を生みます。& がなければ、a :hover { となり、a:hover の間にスペースが入ってしまい、ホバーリンクにスタイルを適用できなくなります。

複数レイヤーでネストすることも可能です — 既にネストされた CSS の中にさらにネストすることが望む限り何層でもできます。ネストは Container Queries、Supports Queries、Media Queries、Cascade Layers と混在させて使用できます。ほとんど何でも何の中にも入れられます。

3. ネストされたスタイル規則

スタイル規則は他のスタイル規則の内部にネストできます。これらの ネストされたスタイル規則 は通常のスタイル規則とまったく同じように動作します — セレクタを介して要素にプロパティを関連付けます — が、親規則のセレクタコンテキストを「継承」し、親のセレクタを繰り返すことなく(場合によっては複数回)そのセレクタに基づいてさらに構築できるようにします。

ネストされたスタイル規則 は通常のスタイル規則とまったく同じですが、相対セレクタ を使用でき、それらは暗黙的に親規則で一致した要素に対して相対的です。

テスト
つまり、 次のようなネストされたスタイル規則は:
.foo {
  color: red;

  a {
    color: blue;
  }
}

は有効であり、次と同等です:

.foo {
  color: red;
}
.foo a {
  color: blue;
}

ネストされた規則はまた ネストセレクタ を使って親規則で一致した要素を直接参照したり、相対セレクタ 構文を用いて「子孫」以外の関係を指定することもできます。

.foo {
  color: red;

  &:hover {
    color: blue;
  }
}

/* equivalent to: */

.foo { color: red; }
.foo:hover { color: blue; }
.foo {
  color: red;

  + .bar {
    color: blue;
  }
}

/* equivalent to: */

.foo { color: red; }
.foo + .bar { color: blue; }
テスト

3.1. 構文

スタイル規則の内容 (style rule) は、既存の 宣言 に加えて、ネストされたスタイル規則アットルール を受け入れるようになりました。

ネストされたスタイル規則 は非ネスト規則と以下の点で異なります:

ネストされたスタイル規則がどのように解析されるかの詳細は [CSS-SYNTAX-3] に定義されています。

無効な ネストされたスタイル規則 は、その内容とともに無視されますが、親規則自体を無効にすることはありません。

相対セレクタ を持つネスト規則は、暗黙的に含まれる ネストセレクタ の特異性を含みます。例えば、.foo { > .bar {...}}.foo { & > .bar {...}} は内側の規則に対して同じ特異性を持ちます。

一部の CSS 生成ツール(プリプロセッサ)はネストを文字列の連結として扱い、ネストレベルをまたいで単一の simple selector を構築することを許すものがあります。これは BEM のような階層的な命名パターンでファイル内の繰り返しを減らすために使われることがあります。

例えば、あるコンポーネントがクラス .foo を使い、ネストされたコンポーネントが .fooBar を使う場合、Sass では次のように書けます:

.foo {
  color: blue;
  &Bar { color: red; }
}
/* In Sass, this is equivalent to
  .foo { color: blue; }
  .fooBar { color: red; }
*/

これは CSS では許されません。ネストは構文変換ではなく、親セレクタが実際に一致する要素に対してマッチするためです。

また、セレクタ &Bar はそもそも CSS では無効です。なぜなら Bar の部分はタイプセレクタであり、複合セレクタの中では先頭に来なければならないからです。(つまり Bar& のように書く必要があります。)したがって幸いにも、CSS ネストとプリプロセッサ構文には重なりはありません。

セレクタが ネストセレクタを含む とは、セレクタを任意のタイプのセレクタとして 解析 したときに、値が "&" (U+0026 AMPERSAND) である <delim-token> が出現した場合を指します。

注: これは :is(:unknown(&), .bar) のようなケースも検出するために明示的に表現されています。未知のセレクタ(未知であるため、その引数がセレクタとして解析される意図なのかどうかを知る手段がない)がネストセレクタを含む唯一の部分である場合でも、それは将来のブラウザで有効になる可能性があり、パースを無関係なバージョン依存にしたくないため、そのような場合もネストセレクタを含むものとして扱います。

もし <forgiving-selector-list> の項目が ネストセレクタを含む が無効である場合、その項目は破棄されずそのまま正確に保持されます。(これはセレクタのマッチ動作を変えるものではありません — 無効なセレクタは依然として何にもマッチしません — ただしシリアライズの結果が変わるだけです。)

テスト

前の段落は & 自体を Selectors に移動するときに Selectors 側に移す必要があります。ここでは便宜上モンキーパッチしています。

3.2.

/* & can be used on its own */
.foo {
  color: blue;
  & > .bar { color: red; }
  > .baz { color: green; }
}
/* equivalent to
  .foo { color: blue; }
  .foo > .bar { color: red; }
  .foo > .baz { color: green; }
*/


/* or in a compound selector,
   refining the parent’s selector */
.foo {
  color: blue;
  &.bar { color: red; }
}
/* equivalent to
  .foo { color: blue; }
  .foo.bar { color: red; }
*/

/* multiple selectors in the list are all
   relative to the parent */
.foo, .bar {
  color: blue;
  + .baz, &.qux { color: red; }
}
/* equivalent to
  .foo, .bar { color: blue; }
  :is(.foo, .bar) + .baz,
  :is(.foo, .bar).qux { color: red; }
*/

/* & can be used multiple times in a single selector */
.foo {
  color: blue;
  & .bar & .baz & .qux { color: red; }
}
/* equivalent to
  .foo { color: blue; }
  .foo .bar .foo .baz .foo .qux { color: red; }
*/

/* & doesn’t have to be at the beginning of the selector */

.foo {
  color: red;
  .parent & {
    color: blue;
  }
}
/* equivalent to
  .foo { color: red; }
  .parent .foo { color: blue; }
*/

.foo {
  color: red;
  :not(&) {
    color: blue;
  }
}
/* equivalent to
  .foo { color: red; }
  :not(.foo) { color: blue; }
*/

/* But if you use a relative selector,
  an initial & is implied automatically */

.foo {
  color: red;
  + .bar + & { color: blue; }
}

/* equivalent to
  .foo { color: red; }
  .foo + .bar + .foo { color: blue; }
*/

/* Somewhat silly, but & can be used all on its own, as well. */
.foo {
  color: blue;
  & { padding: 2ch; }
}
/* equivalent to
  .foo { color: blue; }
  .foo { padding: 2ch; }

  // or

  .foo {
    color: blue;
    padding: 2ch;
  }
*/

/* Again, silly, but can even be doubled up. */
.foo {
  color: blue;
  && { padding: 2ch; }
}
/* equivalent to
  .foo { color: blue; }
  .foo.foo { padding: 2ch; }
*/

/* The parent selector can be arbitrarily complicated */
.error, #404 {
  &:hover > .baz { color: red; }
}
/* equivalent to
  :is(.error, #404):hover > .baz { color: red; }
*/

.ancestor .el {
  .other-ancestor & { color: red; }
}
/* equivalent to
  .other-ancestor :is(.ancestor .el) { color: red; }

/* As can the nested selector */
.foo {
  & :is(.bar, &.baz) { color: red; }
}
/* equivalent to
  .foo :is(.bar, .foo.baz) { color: red; }
*/

/* Multiple levels of nesting "stack up" the selectors */
figure {
  margin: 0;

  > figcaption {
    background: hsl(0 0% 0% / 50%);

    > p {
      font-size: .9rem;
    }
  }
}
/* equivalent to
  figure { margin: 0; }
  figure > figcaption { background: hsl(0 0% 0% / 50%); }
  figure > figcaption > p { font-size: .9rem; }
*/

/* Example usage with Cascade Layers */
@layer base {
  html {
    block-size: 100%;

    body {
      min-block-size: 100%;
    }
  }
}
/* equivalent to
  @layer base {
    html { block-size: 100%; }
    html body { min-block-size: 100%; }
  }
*/

/* Example nesting Cascade Layers */
@layer base {
  html {
    block-size: 100%;

    @layer support {
      body {
        min-block-size: 100%;
      }
    }
  }
}
/* equivalent to
  @layer base {
    html { block-size: 100%; }
  }
  @layer base.support {
    html body { min-block-size: 100%; }
  }
*/

/* Example usage with Scoping */
@scope (.card) to (> header) {
  :scope {
    inline-size: 40ch;
    aspect-ratio: 3/4;

    > header {
      border-block-end: 1px solid white;
    }
  }
}
/* equivalent to
  @scope (.card) to (> header) {
    :scope { inline-size: 40ch; aspect-ratio: 3/4; }
    :scope > header { border-block-end: 1px solid white; }
  }
*/

/* Example nesting Scoping */
.card {
  inline-size: 40ch;
  aspect-ratio: 3/4;

  @scope (&) to (> header > *) {
    :scope > header {
      border-block-end: 1px solid white;
    }
  }
}

/* equivalent to
  .card { inline-size: 40ch; aspect-ratio: 3/4; }
  @scope (.card) to (> header > *) {
    :scope > header { border-block-end: 1px solid white; }
  }
*/

3.3. 他のアットルールのネスト

ネストされたスタイル規則 に加えて、 この仕様は ネストされたグループ規則スタイル規則 の内部に許可します: 本文に スタイル規則 を含む任意のアットルールは、 別段の指定がない限り スタイル規則 の内部にネストできます。

このようにネストされた場合、 ネストされたグループ規則 のブロックの内容は <block-contents> として解析され、<rule-list> とはなりません:

具体的には、次の規則が ネストされたグループ規則 になり得ます:
テスト

そのような ネストされたグループ規則 の意味と挙動は、 別段の指定がない限りそれ以外は変更されません。

例えば、次の条件付きネストは有効です:
/* プロパティは直接使用できます */
.foo {
  display: grid;

  @media (orientation: landscape) {
    grid-auto-flow: column;
  }
}

/* 等価: */
.foo { display: grid;
}
@media (orientation: landscape) {
  .foo {
    grid-auto-flow: column
  }
}

/* またネストされていないものとも等価: */
.foo { display: grid;
}

@media (orientation: landscape) {
  .foo {
    grid-auto-flow: column;
  }
}

/* 条件付きルールはさらにネストできます */
.foo {
  display: grid;

  @media (orientation: landscape) {
    grid-auto-flow: column;

    @media (min-width > 1024px) {
      max-inline-size: 1024px;
    }
  }
}

/* 等価 */
.foo { display: grid;
}

@media (orientation: landscape) {
  .foo {
    grid-auto-flow: column;
  }
}

@media (orientation: landscape) and (min-width > 1024px) {
  .foo {
    max-inline-size: 1024px;
  }
}

/* ネストされた Cascade Layers の例 */
html {
  @layer base {
    block-size: 100%;

    @layer support {
      & body {
        min-block-size: 100%;
      }
    }
  }
}

/* 等価 */
@layer base {
  html { block-size: 100%; }
}
@layer base.support {
  html body { min-block-size: 100%; }
}

/* ネストされた Scoping の例 */
.card {
  inline-size: 40ch;
  aspect-ratio: 3/4;

  @scope (&) {
    :scope {
      border: 1px solid white;
    }
  }
}

/* 等価 */
.card { inline-size: 40ch; aspect-ratio: 3/4; }
@scope (.card) {
  :scope { border-block-end: 1px solid white; }
}

直接ネストされたプロパティが連続している場合、それらは自動的に ネストされた宣言規則 でラップされます。 (これは CSSOM で観察できます。)

テスト

3.3.1. ネストされた @scope 規則

@scope ルールが ネストされたグループ規則 である場合、 &<scope-start> セレクタ内にあるとき、 それは最も近い祖先スタイル規則で一致した要素を参照します。

つまり、次のコードは:
.parent {
  color: blue;

  @scope (& > .scope) to (& .limit) {
    & .content {
      color: red;
    }
  }
}

次と等価です:

.parent { color: blue; }
@scope (.parent > .scope) to (:where(:scope) .limit) {
  :where(:scope) .content {
    color: red;
  }
}
アンパサンド(&)セレクタは :where(:scope) のように @scope ルール内で振る舞います。

3.4. ネスト規則と宣言の混在

あるスタイル規則が宣言と ネストされたスタイル規則ネストされたグループ規則 の両方を含む場合、 それら三者は任意に混在できます。 規則の後や規則の間に来る宣言は、 他の規則に対する順序を保持するために暗黙的に ネストされた宣言規則 でラップされます。

例えば、次のコードでは:
article {
  color: green;
  & { color: blue; }
  color: red;
}

/* 等価 */
article { color: green; }
:is(article) { color: blue; }
article { color: red; }

/* 等価ではない */
article { color: green; }
article { color: red; }
:is(article) { color: blue; }

「出現順序(Order Of Appearance)」を決定する目的のために、ネストされたスタイル規則ネストされたグループ規則 は、その親規則の後に来るものと見なされます。

例えば:
article {
  color: blue;
  & { color: red; }
}

両方の宣言は同じ特異性 (0,0,1) を持ちますが、 ネストされた規則は親規則の後に来ると見なされるため、 color: red の宣言がカスケードで勝ちます。

一方、次の例では:

article {
  color: blue;
  :where(&) { color: red; }
}

:where() 疑似クラスはネストセレクタの特異性を 0 に減らすため、 ネストセレクタ を含む宣言である color: red は特異性が (0,0,0) となり、 「出現順序」が考慮される前に color: blue の宣言に負けます。

注意:宣言とネストされたルールを自由に組み合わせることは可能ですが、 後のプロパティが自動的にネストされた宣言ルールに 包まれるため、読みづらく多少混乱を招くことがあります。 可読性のために、著者はスタイルルール内のすべてのプロパティを ネストルールの前に配置することを推奨します。 (これは古いユーザーエージェントでも若干有利に働きます: パースやエラー回復の仕組みによって、ネストルールの後に出現するプロパティが スキップされることがあるためです。)

4. ネストセレクタ: & セレクタ

ネストされたスタイル規則を使用する際には、 親規則で一致した要素を参照できる必要があります; それこそがネストの目的の全てです。 それを実現するために、 この仕様は新しいセレクタ、ネストセレクタを定義します。 表記は & (U+0026 AMPERSAND) です。

ネストされたスタイル規則 のセレクタで使用された場合、 ネストセレクタは 親規則で一致した要素を表します。 他の文脈で使用された場合は、 その文脈における :scope と同じ要素を表します (別段の定義がない限り)。

テスト
ネストセレクタは、 親のスタイル規則のセレクタで置き換え、:is() セレクタでラップすることで展開(デシュガー)できます。 例えば、
a, b {
  & c { color: blue; }
}

は次と等価です

:is(a, b) c { color: blue; }

ネストセレクタは 疑似要素を表すことはできません (これは :is() 疑似クラスの挙動と同じです)。

例えば、次のスタイル規則では:
.foo, .foo::before, .foo::after {
  color: red;

  &:hover { color: blue; }
}

アンパサンド(&)は .foo にマッチする要素のみを表します; 言い換えれば、次と等価です:

.foo, .foo::before, .foo::after {
  color: red;
}
.foo:hover {
  color: blue;
}

この制限を緩和したいと考えていますが、 :is()& の両方を同時に扱う必要があるため、 それらは同じ内部メカニズムに基づいて意図的に構築されています。 (Issue 7433

特異性は、ネストセレクタのものは、 親スタイル規則のセレクタリスト内の複合セレクタ群のうち最大の特異性に等しいです (これは :is() の挙動と同じです)、 もしそのようなセレクタリストが存在しない場合は 0 になります。

テスト
例えば、次のスタイル規則が与えられた場合:
#a, b {
  & c { color: blue; }
}
.foo c { color: red; }

次のような DOM 構造では

<b class=foo>
  <c>Blue text</c>
</b>

テキストは赤ではなく青になります。 & の特異性は #a([1,0,0])と b([0,0,1])のうち大きい方であり、 したがって [1,0,0] になり、 全体の & c セレクタの特異性は [1,0,1] となり、 .foo c([0,1,1]) より大きくなります。

注目すべきは、これはネストを手動で展開して非ネスト規則にした場合とは異なる結果になる点です。 その場合、color: blue の宣言は b c セレクタ([0,0,2])によってマッチすることになり、 #a c([1,0,1])ではありません。

なぜ特異性が非ネスト規則と異なるのか?

ネストセレクタは意図的に :is() 疑似クラスと同じ特異性ルールを使用します。 すなわち引数の中で最大の特異性を使用し、 実際にどのセレクタがマッチしたかを追跡しません。

これはパフォーマンス上の理由で必要です; セレクタがマッチした方法に応じて複数の可能な特異性を持つと、 セレクタマッチの処理が非常に複雑かつ遅くなります。

それでも疑問は残ります: なぜ &:is() に基づいて定義するのでしょうか? Nesting っぽい機能を持つ一部の非ブラウザ実装は :is() にデシュガーしないことがあり、 主にそれらは :is() の導入以前に存在したためです。 代わりに直接展開(desugar)します; しかしそれは重大な問題をもたらします — いくつかの(比較的一般的な)ケースで 可能性の組み合わせが指数的に爆発し、巨大なセレクタを偶然生成することがあるのです。

.a1, .a2, .a3 {
  .b1, .b2, .b3 {
    .c1, .c2, .c3 {
      ...;
    }
  }
}

/* 単純にデシュガーすると */
.a1 .b1 .c1,
.a1 .b1 .c2,
.a1 .b1 .c3,
.a1 .b2 .c1,
.a1 .b2 .c2,
.a1 .b2 .c3,
.a1 .b3 .c1,
.a1 .b3 .c2,
.a1 .b3 .c3,
.a2 .b1 .c1,
.a2 .b1 .c2,
.a2 .b1 .c3,
.a2 .b2 .c1,
.a2 .b2 .c2,
.a2 .b2 .c3,
.a2 .b3 .c1,
.a2 .b3 .c2,
.a2 .b3 .c3,
.a3 .b1 .c1,
.a3 .b1 .c2,
.a3 .b1 .c3,
.a3 .b2 .c1,
.a3 .b2 .c2,
.a3 .b2 .c3,
.a3 .b3 .c1,
.a3 .b3 .c2,
.a3 .b3 .c3 {...}

ここでは、3 レベルのネストがあり、 各レベルに 3 つのセレクタがあるため、 27 個の展開セレクタが生成されました。 リストにさらにセレクタを加えたり、 ネストのレベルを増やしたり、 ネスト規則をより複雑にすると、 比較的小さな規則が数メガバイト(あるいはそれ以上)のセレクタに拡張されることがあります。

一部の CSS ツールはヒューリスティックにいくつかの組み合わせを破棄することで最悪ケースを回避し、 出力を減らして「おそらく」正しい結果にしますが、 それは UA にとって許容できる選択肢ではありません。

:is() を使ったデシュガーは この問題を完全に排除しますが、 その代償として特異性が多少有用性を失うことになり、 それが妥当なトレードオフだと判断されました。

ネストセレクタは、 親規則でマッチしていた場合に限り、特徴のない(featureless) 要素にもマッチできます。

ネストセレクタ複合セレクタ内にある位置は 振る舞いに差を与えません (つまり &.foo.foo& は同じ要素にマッチします)、 ただし既存のルールである、タイプセレクタ が存在する場合は複合セレクタの先頭に来なければならない という規則は引き続き適用されます (つまり &div は不正であり、代わりに div& と書く必要があります)。

テスト

5. ネストされた宣言ルール

やや技術的な理由から、 スタイル規則の内容の先頭に現れるプロパティと 他の規則と入り混じって現れるプロパティを区別できることが重要です。

例えば、次の二つの規則では:
.foo {
  color: red;
  @media (...) {...}
  background: blue;
}

我々は color: redbackground: blue を少し異なって扱う必要があります。 特に、CSSOM では、 color: red はスタイル規則の style 属性に公開されますが、 background: blue は代わりに cssRules リストに表示される必要があります。

これを実現するために、CSS の解析はこのようなプロパティを自動的に特別な子規則でラップします。 しかし、それらを スタイル規則 として、 & セレクタでラップすると、 いくつか望ましくない挙動が発生します:

例えば、次の場合:
.foo, .foo::before {
  color: red;
  & {
    background: blue;
  }
}

ネストされた規則は background.foo::before 要素に適用しません。 その理由はアンパサンド(&)が疑似要素を表せないためです。

同様に、ネストされた非スタイル規則の子宣言は何らかの方法で 規則 として公開される必要があります。 というのも、これらの種類の規則(例えば @media)はこれまで style プロパティを持たなかったからです。 これらは上記と同じ問題に直面します。

これらすべての問題に対処するために、 我々は直接ネストされた連続するプロパティの列を ネストされた宣言規則でラップします。

別段の指定がない限り、 ネストされた宣言規則ネストされたスタイル規則であり、 他のスタイル規則と同一に動作します。 それは親スタイル規則とまったく同じ要素と疑似要素にマッチし、 同じ特異性の振る舞いを持ちます。(これは & セレクタを持つスタイル規則と類似していますが、上で説明したようにやや強力です。)

なぜ ネストされた宣言規則 が存在するのか?

元々は、この仕様はスタイル規則内のすべての宣言をまとめ、 それらを規則の先頭に置かれたかのように「移動」していました。 また生の宣言を ネストされたグループ規則 の中で自動的に平文のスタイル規則でラップし、 & セレクタを使用していました。

我々が ネストされた宣言規則 に切り替えた理由は主に二つあります。

第一に、& {...} 規則を使って暗黙的に宣言を ネストされたグループ規則 にラップすることは挙動を変えてしまいます。 このノートの後の例に示されるように、 親スタイル規則が疑似要素を含む場合に破綻し、 それがない場合でもネストされた宣言の特異性の振る舞いを変える可能性があります。 ネストされた宣言規則 に切り替えることでこれらの問題を避け、 ネストされた @media 等の振る舞いを *非ネストの* @media 等と同一にします。

第二に、将来の CSS 機能(特に「ミキシン」)のいくつかの詳細は、 宣言が自動的にスタイル規則の先頭に移動されると正しく動作しません。 我々はそれらの宣言を他の規則との相対的な順序を保持する必要があり、 それを CSSOM で表現するためには何らかのルールでラップする必要があります。 単に通常の & {...} 規則を使うと前段の問題が再発するため、 ネストされた宣言規則 を用いることで副作用なしにこれを可能にしています。

例えば、次のスタイルシート断片では:
.foo, .foo::before, .foo::after {
  color: black;
  @media (prefers-color-scheme: dark) {
    & {
      color: white;
    }
  }
}

ダークモードのページでは、 .foo 要素のテキスト色は白に変わりますが、 ::before::after 疑似要素は黒のままになります。 その理由は & セレクタが疑似要素を表せないためです。

しかし、代わりに次のように書かれていた場合:

.foo, .foo::before, .foo::after {
  color: black;
  @media (prefers-color-scheme: dark) {
    color: white;
  }
}

その場合、color: white は暗黙的に ネストされた宣言規則でラップされ、 その子規則は親のスタイル規則と正確に同じものにマッチすることが保証されるため、 要素とその疑似要素の両方がダークモード時に白いテキストになります。

規則と入り混じった宣言は暗黙的に ネストされた宣言規則でラップされ、 それらを別のスタイル規則の一部にします。 例えば、次の CSS が与えられたとします:
.foo {
  color: black;
  @media (...) {...}
  background: silver;
}

もし .foo ルールの CSSOM オブジェクトを調べると、 その style 属性には宣言は一つだけ入っています: color: black です。

background: silver の宣言は 暗黙的に作成された ネストされた宣言の子規則 に見つかります、 位置は fooRule.cssRules[1].style です。

テスト

6. CSSOM

注: [CSSOM-1] は現在、 CSSStyleRule が子規則を持てることを定義しています。

ネストされた 相対セレクタネストされたスタイル規則 内でシリアライズする際、 そのセレクタは絶対化され、 暗黙の ネストセレクタ が挿入されなければなりません。

例えば、セレクタ > .foo& > .foo としてシリアライズされます。
テスト

6.1. The CSSNestedDeclarations Interface

The CSSNestedDeclarations interface は ネストされた宣言規則 を表します。

[Exposed=Window]
interface CSSNestedDeclarations : CSSRule {
  [SameObject, PutForwards=cssText] readonly attribute CSSStyleProperties style;
};
The style attribute はルールのための CSSStyleProperties オブジェクトを返さなければならず、次のプロパティを持ちます:
computed flag

未設定

readonly flag

未設定

declarations

ルール内の宣言。指定順序 に従います。

parent CSS rule

this

owner node

Null

The CSSNestedDeclarations ルールは、その 宣言ブロック が直接 シリアライズされたかのようにシリアライズされます。

テスト

注: これは、隣接する複数の ネストされた宣言規則(例えば insertRule で作成可能)が、 シリアライズして再解析すると単一の規則に折りたたまれることを意味します。

プライバシー上の考慮事項

この仕様に関して新たなプライバシー上の考慮事項は報告されていません。

セキュリティ上の考慮事項

この仕様に関して新たなセキュリティ上の考慮事項は報告されていません。

7. 変更点

2023年2月14日の作業草案(Feb 14, 2023 Working Draft)以降の主な変更点:

適合性 (Conformance)

文書上の慣例

適合要件は記述的な断言と RFC 2119 用語の組み合わせで表現されています。キーワード “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, および “OPTIONAL” は、本書の規範的部分において RFC 2119 に従って解釈されます。 ただし可読性のため、これらの語は本仕様ではすべて大文字で表記されない場合があります。

本仕様の本文は、非規範と明示された節、例、および注を除きすべて規範的です。[RFC2119]

本仕様の例は “for example” という語で導入されるか、class="example" のように規範的な本文から区別されます。

これは説明的な例の例です。

説明的注記は “Note” で始まり、class="note" で示されます。

注:これは説明的な注記です。

助言的な節は注意を喚起するために様式化された規範節であり、<strong class="advisement"> で区別されます。例えば: UAs は必ず代替のアクセシビリティ手段を提供しなければなりません。

テスト

本仕様の内容に関連するテストは、このような “Tests” ブロックに記載されることがあります。 そのようなブロックはすべて説明的です。


適合クラス

本仕様への適合は三つの適合クラスで定義されます:

スタイルシート
CSS スタイルシート
レンダラ
スタイルシートの意味を解釈し文書をレンダリングする UA
作成ツール
スタイルシートを書く UA

あるスタイルシートは、本モジュールで定義された構文を使用する全ての記述が汎用 CSS 文法および各機能の文法に従って有効である場合、本仕様に適合します。

レンダラは、適切な仕様に従ってスタイルシートを解釈することに加え、本仕様で定義された全ての機能を正しく解析して文書をレンダリングすることで本仕様に適合します。なお、デバイスの制約により文書を正しくレンダリングできないことは UA を非適合にするものではありません(例: モノクロモニタで色をレンダリングする必要はありません)。

作成ツールは、スタイルシートが汎用 CSS 文法および本モジュール内の各機能の個別文法に従って構文的に正しく、かつ本モジュールのスタイルシートに関する他の適合要件を満たす場合、本仕様に適合します。

部分的実装

フォワード互換の解析規則を利用してフォールバック値を割り当てられるようにするため、CSS レンダラはサポートがない構文上の構成要素(アットルール、プロパティ、値、キーワード等)を無効として扱い(かつ適切に無視)しなければなりません。特に、UA はサポートされていないコンポーネント値を選択的に無視して、同じ複数値プロパティ宣言の中でサポートされる値だけを適用してはなりません:もし任意の値が無効と見なされるなら(サポートされない値はそう扱われるべきです)、CSS はその宣言全体を無視することを要求します。

不安定または独自機能の実装

将来の安定した CSS 機能との衝突を避けるため、CSSWG は不安定機能や独自拡張の実装に関して ベストプラクティスに従う ことを推奨します。

実験的でない実装

仕様が Candidate Recommendation に達した場合、実験的でない実装が可能になり、実装者は CR レベルの機能を仕様に従って正しく実装できると示せるならば、プレフィックスなし実装をリリースすべきです。

CSS の相互運用性を確立・維持するため、CSS Working Group は実験的でない CSS レンダラに対して、プレフィックスなし実装をリリースする前に実装報告書(必要ならばその実装で用いたテストケース)を W3C に提出することを要請します。提出されたテストケースは CSS Working Group によるレビューと修正の対象となります。

テストケースと実装報告書の提出に関する詳細は CSS Working Group のサイト https://www.w3.org/Style/CSS/Test/ を参照してください。質問は public-css-testsuite@w3.org メーリングリストへ送ってください。

索引

本仕様で定義された用語

参照で定義された用語

参考文献

規範的参照

[CSS-CASCADE-4]
Elika Etemad; Tab Atkins Jr.. CSS Cascading and Inheritance Level 4. 13 January 2022. CR. URL: https://www.w3.org/TR/css-cascade-4/
[CSS-CASCADE-6]
Elika Etemad; Miriam Suzanne; Tab Atkins Jr.. CSS Cascading and Inheritance Level 6. 6 September 2024. WD. URL: https://www.w3.org/TR/css-cascade-6/
[CSS-COLOR-4]
Chris Lilley; Tab Atkins Jr.; Lea Verou. CSS Color Module Level 4. 24 April 2025. CRD. URL: https://www.w3.org/TR/css-color-4/
[CSS-CONDITIONAL-3]
Chris Lilley; David Baron; Elika Etemad. CSS Conditional Rules Module Level 3. 15 August 2024. CRD. URL: https://www.w3.org/TR/css-conditional-3/
[CSS-SYNTAX-3]
Tab Atkins Jr.; Simon Sapin. CSS Syntax Module Level 3. 24 December 2021. CRD. URL: https://www.w3.org/TR/css-syntax-3/
[CSS21]
Bert Bos; et al. Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification. 7 June 2011. REC. URL: https://www.w3.org/TR/CSS2/
[CSSOM-1]
Daniel Glazman; Emilio Cobos Álvarez. CSS Object Model (CSSOM). 26 August 2021. WD. URL: https://www.w3.org/TR/cssom-1/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[SELECTORS-4]
Elika Etemad; Tab Atkins Jr.. Selectors Level 4. 11 November 2022. WD. URL: https://www.w3.org/TR/selectors-4/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. Living Standard. URL: https://webidl.spec.whatwg.org/

説明的参照

[CSS-BACKGROUNDS-3]
Elika Etemad; Brad Kemper. CSS Backgrounds and Borders Module Level 3. 11 March 2024. CRD. URL: https://www.w3.org/TR/css-backgrounds-3/
[CSS-CASCADE-5]
Elika Etemad; Miriam Suzanne; Tab Atkins Jr.. CSS Cascading and Inheritance Level 5. 13 January 2022. CR. URL: https://www.w3.org/TR/css-cascade-5/
[CSS-CONDITIONAL-5]
Chris Lilley; et al. CSS Conditional Rules Module Level 5. 30 October 2025. WD. URL: https://www.w3.org/TR/css-conditional-5/
[CSS-PSEUDO-4]
Elika Etemad; Alan Stearns. CSS Pseudo-Elements Module Level 4. 27 June 2025. WD. URL: https://www.w3.org/TR/css-pseudo-4/
[CSS-UI-4]
Tab Atkins Jr.; Florian Rivoal. CSS Basic User Interface Module Level 4. 20 January 2026. WD. URL: https://www.w3.org/TR/css-ui-4/

IDL 索引

[Exposed=Window]
interface CSSNestedDeclarations : CSSRule {
  [SameObject, PutForwards=cssText] readonly attribute CSSStyleProperties style;
};

問題索引

前の段落は & 自体を Selectors に移動するときに Selectors 側に移す必要があります。ここでは便宜上モンキーパッチしています。
我々はこの制限を緩和したいと考えていますが、 :is()& の両方を同時に扱う必要があるため、 それらは意図的に同じ基礎的メカニズムに基づいて構築されています。 (Issue 7433