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

W3C作業草案,

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

概要

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

CSSは、構造化文書(HTMLやXMLなど)の表示を画面や紙などで記述するための言語です。

この文書のステータス

このセクションは、公開時点でのこの文書のステータスについて説明します。 現在のW3C出版物の一覧や この技術報告の最新改訂版は W3C技術報告インデックス https://www.w3.org/TR/で確認できます。

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

この文書はドラフト文書であり、今後いつでも更新、置き換え、または他の文書によって廃止される可能性があります。 この文書を進行中の作業以外として引用するのは不適切です。

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

この文書は2021年11月2日W3Cプロセス文書に則っています。

この文書はW3C特許ポリシーの下で運営されているグループによって作成されました。 W3Cは、グループの成果物に関連して行われた特許開示の公開リストを管理しています。 そのページには特許開示方法の案内もあります。 特許の存在を実際に知っている個人は、その特許に必須クレームが含まれていると考える場合、W3C特許ポリシー第6節に従って情報を開示しなければなりません。

1. はじめに

このセクションは規範的ではありません。

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

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

このモジュールは、[CSS21] パーサーモデルを拡張する新しいパーサー規則を導入します。 また、[SELECTORS4] モジュールを拡張するセレクターも導入します。

1.2.

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

1.3. 動機

CSSは、多少複雑なウェブページの場合でも、 関連するコンテンツをスタイリングするために多くの重複を含むことがよくあります。 例えば、これは [CSS-COLOR-3] モジュールのあるバージョンのCSSマークアップの一部です:

table.colortable td {
  text-align:center;
}
table.colortable td.c {
  text-transform:uppercase;
}
table.colortable td:first-child, table.colortable td:first-child+td {
  border:1px solid black;
}
table.colortable th {
  text-align:center;
  background:black;
  color:white;
}

入れ子を使うと、関連するスタイル規則を次のようにまとめることができます:

table.colortable {
  & td {
    text-align:center;
    &.c { text-transform:uppercase }
    &:first-child, &:first-child + td { border:1px solid black }
  }
  & th {
    text-align:center;
    background:black;
    color:white;
  }
}

重複を減らせるだけでなく、 関連する規則のグループ化によって、CSSの可読性と保守性が向上します。

2. スタイル規則の入れ子

スタイル規則は他のスタイル規則の中に入れ子にできます。 これらの 入れ子スタイル規則 は通常のスタイル規則と同様に、 セレクターを使って要素にプロパティを関連付けますが、親規則のセレクターコンテキストを「継承」し、 親のセレクターを繰り返すことなく、さらにその上に構築することができます。

入れ子スタイル規則は、通常のスタイル規則とほぼ同じですが、 その セレクター識別子関数表記で始めることはできません。 さらに、入れ子スタイル規則相対セレクターを使用することができます。

つまり、次のような入れ子スタイル規則は:
.foo {
  color: red;

  .bar {
    color: blue;
  }
}

有効であり、次と同等になります:

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

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

.foo {
  color: red;

  &:hover {
    color: blue;
  }
}

/* 次と同等: */

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

  + .bar {
    color: blue;
  }
}

/* 次と同等: */

.foo { color: red; }
.foo + .bar { color: blue; }
ただし、入れ子セレクターを識別子(つまり 型セレクター)で始めるのは無効です:
div {
  color: red;

  input {
    margin: 1em;
  }
}
/* 「input」は識別子なので無効 */

このようなセレクターも書くことはできますが、少し書き換える必要があります:

div {
  color: red;

  & input { margin: 1em; }
  /* 有効、識別子で始まらない */

  :is(input) { margin: 1em; }
  /* 有効、コロンで始まり、
     前の規則と同等 */
}
なぜ入れ子規則のセレクターに制約があるのですか?

スタイル規則を他のスタイル規則の中に素直に入れ子にすると、残念ながら曖昧になります。セレクターの構文が宣言の構文と重複するため、 パーサーは宣言なのかスタイル規則の始まりなのかを判断するために無限の先読みが必要になります。

例えば、パーサーが color:hover ... を見たとき、 それが color プロパティ (無効な値が設定されている...) なのか、<color> 要素のセレクターなのか、区別できません。 有効なプロパティを探すことで判別することもできません。 実装がサポートするプロパティによってパースが変わってしまい、時期によっても変化してしまうためです。

入れ子スタイル規則が 識別子で始まることを禁止することでこの問題を回避できます。 宣言はすべて識別子で始まり、 その識別子がプロパティ名となるため、 パーサーはすぐに 宣言スタイル規則か判断できます。

一部の非ブラウザー実装ではこの制約を課していません。 多くの場合、最終的にはプロパティとセレクターを区別できますが、 それにはパーサーが無限の先読みを必要とします。 つまり、どちらとして解釈するべきか判断できるまで不明な量の内容を保持しなければなりません。 CSSはこれまで、パース時の先読み量が少なく、既知であることを要求してきました。 これにより効率的なパースアルゴリズムが可能となり、 無限先読みはCSSのブラウザー実装では一般に容認されていません。

2.1. 構文

スタイル規則の内容には、従来の宣言に加えて、新たに入れ子スタイル規則アットルールが許可されます。

入れ子スタイル規則は、非入れ子規則と次の点で異なります:

入れ子スタイル規則のパース方法の詳細は[CSS-SYNTAX-3]で定義されています。

CSSWGは現在、パース時の先読みの影響を検討しており、 その結果として許可される構文を調整する可能性があります。[Issue #7961]

無効な入れ子スタイル規則は、その内容ごと無視されますが、親規則自体は無効になりません。

例えば、次の入れ子は有効です:
/* & は単独でも利用可能 */
.foo {
  color: blue;
  & > .bar { color: red; }
  > .baz { color: green; }
}
/* 同等:
  .foo { color: blue; }
  .foo > .bar { color: red; }
  .foo > .baz { color: green; }
*/


/* 複合セレクターで、親のセレクターを絞り込む */
.foo {
  color: blue;
  &.bar { color: red; }
}
/* 同等:
  .foo { color: blue; }
  .foo.bar { color: red; }
*/

/* セレクターリストの複数のセレクターはすべて親に相対 */
.foo, .bar {
  color: blue;
  + .baz, &.qux { color: red; }
}
/* 同等:
  .foo, .bar { color: blue; }
  :is(.foo, .bar) + .baz,
  :is(.foo, .bar).qux { color: red; }
*/

/* & は1つのセレクター内で複数回使用可能 */
.foo {
  color: blue;
  & .bar & .baz & .qux { color: red; }
}
/* 同等:
  .foo { color: blue; }
  .foo .bar .foo .baz .foo .qux { color: red; }
*/

/* & はセレクターの先頭でなくてもよい */

.foo {
  color: red;
  .parent & {
    color: blue;
  }
}
/* 同等:
  .foo { color: red; }
  .parent .foo { color: blue; }
*/

.foo {
  color: red;
  :not(&) {
    color: blue;
  }
}
/* 同等:
  .foo { color: red; }
  :not(.foo) { color: blue; }
*/

/* 相対セレクターを使う場合、
  先頭の & は自動的に暗黙指定される */

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

/* 同等:
  .foo { color: red; }
  .foo + .bar + .foo { color: blue; }
*/

/* ちょっと変ですが、& 単独でも利用可能 */
.foo {
  color: blue;
  & { padding: 2ch; }
}
/* 同等:
  .foo { color: blue; }
  .foo { padding: 2ch; }

  // または

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

/* さらに、& の重複も可能 */
.foo {
  color: blue;
  && { padding: 2ch; }
}
/* 同等:
  .foo { color: blue; }
  .foo.foo { padding: 2ch; }
*/

/* 親セレクターは任意に複雑にできる */
.error, #404 {
  &:hover > .baz { color: red; }
}
/* 同等:
  :is(.error, #404):hover > .baz { color: red; }
*/

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

/* 入れ子セレクターも複雑にできる */
.foo {
  & :is(.bar, &.baz) { color: red; }
}
/* 同等:
  .foo :is(.bar, .foo.baz) { color: red; }
*/

/* 入れ子の多段構造ではセレクターが積み重なる */
figure {
  margin: 0;

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

    > p {
      font-size: .9rem;
    }
  }
}
/* 同等:
  figure { margin: 0; }
  figure > figcaption { background: hsl(0 0% 0% / 50%); }
  figure > figcaption > p { font-size: .9rem; }
*/
		
/* Cascade Layersの利用例 */
@layer base {
  html {
    block-size: 100%;

    & body {
      min-block-size: 100%;
    }
  }
}
/* 同等:
  @layer base {
    html { block-size: 100%; }
    html body { min-block-size: 100%; }
  }
*/

/* Cascade Layersの入れ子利用例 */
@layer base {
  html {
    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の利用例 */
@scope (.card) to (> header) {
  :scope {
    inline-size: 40ch;
    aspect-ratio: 3/4;
				
    > header {
      border-block-end: 1px solid white;
    }
  }
}
/* 同等:
  @scope (.card) to (> header) {
    :scope { inline-size: 40ch; aspect-ratio: 3/4; }
    :scope > header { border-block-end: 1px solid white; }
  }
*/

/* Scopingの入れ子利用例 */
.card {
  inline-size: 40ch;
  aspect-ratio: 3/4;

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

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

ただし、次のような場合は無効です:

/* セレクターが識別子で始まる */
.foo {
  color: blue;
  div {
    color: red;
  }
}
ネスティングをプリプロセスするCSS生成ツールの中には、 セレクターを文字列として連結し、入れ子レベルをまたいで単一の単純セレクターを構築できるようにするものもあります。 これはBEMのような階層的な命名パターンで、ファイル内での繰り返しを減らすために使われることがあります。 セレクター自体に内部的な繰り返しが多い場合に便利です。

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

.foo {
        color: blue;
        &Bar { color: red; }
}
/* Sassでは同等:
   .foo { color: blue; }
   .fooBar { color: red; }
*/

しかし、この文字列ベースの解釈は、 著者が入れ子規則で型セレクターを追加しようとした場合に曖昧になります。例えばBarは HTMLのカスタム要素名として有効です。

CSSはこうした連結を行わず、 入れ子セレクターの各部を個別に解釈します:

.foo {
        color: blue;
        &Bar { color: red; }
}
/* CSSでは同等:
   .foo { color: blue; }
   Bar.foo { color: red; }
*/

2.2. 他のアットルールの入れ子

入れ子スタイル規則に加えて、 この仕様では入れ子グループ規則スタイル規則の中に入れ子にすることを許可します。 本体にスタイル規則を含むアットルールは、スタイル規則内に入れ子にすることができます。

このように入れ子にされた場合、 入れ子グループ規則の内容は <style-block>としてパースされ、 <stylesheet>とは異なります:

具体的には、次の規則が入れ子グループ規則として入れ子にできます:

これら入れ子グループ規則の意味や挙動は、特に指定がない限り変更されません。

例えば、次のような条件付きの入れ子は有効です:
/* プロパティを直接利用可能 */
.foo {
  display: grid;

  @media (orientation: landscape) {
    grid-auto-flow: column;
  }
}
/* 同等:
  .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) {
    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; }
  }
*/

直接入れ子にされたプロパティはすべて、 まとめて順に集められ、 入れ子スタイル規則 (セレクター&)として入れ子規則の先頭に配置されます。 OMでも同様です。 (つまり、childRules属性は まずこの入れ子スタイル規則から始まり、 直接入れ子にされたすべてのプロパティを含みます。)

例えば、先ほどの例:

.foo {
  display: grid;

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

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

は、まさに同等であり、CSSOM構造も全く同じになります。 CSSMediaRule オブジェクトには CSSStyleRule オブジェクトが1つあり、 その.childRules属性内に grid-auto-flowプロパティが含まれます。

注: このため、このような規則のシリアライズは 元の記述方法と異なり、 シリアライズには直接入れ子のプロパティが一切含まれません

2.2.1. 入れ子の @scope 規則

@scope規則が入れ子グループ規則の場合、 &<scope-start>セレクター内で、 最も近い祖先のスタイル規則で一致した要素を参照します。

本体のスタイル規則や自身の<scope-end> セレクターにおいては、 @scope規則は祖先スタイル規則として扱われ、 <scope-start>で一致した要素をマッチします。

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

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

次のように同等です:

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

2.3. 入れ子規則と宣言の混合

スタイル規則内に宣言と 入れ子スタイル規則入れ子条件付きグループ規則が混在している場合、 3つは自由に混ぜることができます。 ただし、宣言と他の規則との相対的な順序は保持されません。

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

/* 同等 */
article {
  color: green;
  color: red;
  & { color: blue; }
}

出現順序を決定する際、 入れ子スタイル規則入れ子条件付きグループ規則は親規則のに来るものとみなされます。

例えば:
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宣言が勝ちます。 この場合は「出現順序」が考慮される前に決着します。

注: 宣言と入れ子規則を自由に混ぜることはできますが、 読みにくく混乱しやすいので、 全てのプロパティはスタイル規則の先頭にまとめ、 入れ子規則は後に書くことが推奨されます。 (古いユーザーエージェントでもこのほうが挙動が良いです。 パースとエラー回復の仕様により、入れ子規則の後に書かれたプロパティは無視されることがあります。)

注: 他の規則と同様、 入れ子がある場合のスタイル規則のシリアライズは元の記述と異なります。 特に、直接入れ子のプロパティは すべて入れ子規則より前にシリアライズされるため、 先にプロパティを書くべきもう一つの理由となります。

3. 入れ子セレクター:& セレクター

入れ子スタイル規則を使用する際、 親規則で一致した要素を参照できる必要があります。 これはつまり、入れ子の主目的です。 これを実現するために、 本仕様は新しいセレクター、 入れ子セレクター を定義します。記述は & (U+0026 アンパサンド) です。

入れ子スタイル規則のセレクター内で使用した場合、 入れ子セレクターは親規則で一致した要素を表します。 他の文脈で使用した場合は、同じ文脈での: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()と同様の挙動)。

例えば、次のスタイル規則がある場合:
#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: blueb c([0,0,2])で一致し、 #a c([1,0,1])ではありません。

なぜ入れ子規則の詳細度は非入れ子規則と違うのですか?

入れ子セレクターは意図的に :is()疑似クラスと同じ詳細度ルールを使用します。 これは、実際に一致したセレクターではなく、引数の中で最大の詳細度を使うというものです。

これはパフォーマンス上の理由です。 複数の詳細度を持つセレクターが一致方法によって変化する場合、 セレクターの一致処理が非常に複雑かつ遅くなります。

では、なぜ&:is()ベースで定義するのでしょうか? 一部の非ブラウザー実装では:is()に展開せず、 直接展開しています(多くは:is()導入前から存在)。 ただし、この方法には深刻な問題があり、 一部のよくあるケースで膨大なセレクターが生成されてしまいます。

.a1, .a2, .a3 {
  .b1, .b3, .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()で展開することで、この問題を完全に回避できます。 詳細度の実用性が多少下がるものの、合理的なトレードオフと判断されました。

入れ子セレクター複合セレクター内のどこでも使えます。 型セレクターの前でも使えます。 複合セレクターの通常の並び順の制約を破ることができます。

例えば、&divは有効な入れ子セレクターであり、 「親規則で一致したもののうち、div要素のみ」を意味します。

同じ意味でdiv&とも書けますが、 これは入れ子スタイル規則の先頭としては無効ですが、セレクターの途中なら使用可能です。

4. CSSOM

4.1. CSSStyleRuleへの修正

CSSスタイル規則は入れ子規則を持てるようになります:

partial interface CSSStyleRule {
  [SameObject] readonly attribute CSSRuleList cssRules;
  unsigned long insertRule(CSSOMString rule, optional unsigned long index = 0);
  undefined deleteRule(unsigned long index);
};

cssRules属性は、 CSSRuleList オブジェクトを子CSS規則として返さなければなりません。

insertRule(rule, index)メソッドは、 CSS規則を挿入を呼び出してrule子CSS規則indexに挿入した結果を返さなければなりません。

deleteRule(index)メソッドは、 CSS規則の削除子CSS規則indexで呼び出さなければなりません。

注: 入れ子規則を含むCSSStyleRuleの シリアライズは [CSSOM]で既に定義済みです。 CSS規則のシリアライズを参照してください。

注: 入れ子スタイル規則のセレクター先頭制約は CSS規則を挿入の手順5「CSSによる制約」に該当します (入れ子スタイル規則を受けるものに適用、CSSStyleRule自体だけでなく)。

selectorTextを設定する際、 CSSStyleRule入れ子スタイル規則で、 返されるセレクター群の先頭が識別子または関数トークンで始まる場合は何もせずリターンします。

上記段落はCSSOMアルゴリズムにインライン化される予定です。

適合性

文書の慣例

適合要件は、記述的な断言と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"で示されます。例:UAはアクセシブルな代替手段を提供しなければなりません。

適合クラス

この仕様への適合性は、3つの適合クラスについて定義されます:

style sheet
CSSスタイルシート
renderer
UA(ユーザーエージェント):スタイルシートの意味を解釈し、スタイルシートを使用する文書をレンダリングするもの。
authoring tool
UA(ユーザーエージェント):スタイルシートを作成するもの。

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

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

オーサリングツールは、汎用CSS文法およびこのモジュールの各機能の個別文法に従って構文的に正しいスタイルシートを出力し、このモジュールで説明されるスタイルシートのその他の適合要件を満たしている場合、本仕様に適合しています。

部分的な実装

著者が前方互換性のあるパース規則を利用してフォールバック値を割り当てられるように、CSSレンダラーは、サポートできないアットルール、プロパティ、プロパティ値、キーワード、およびその他の構文要素を無効として(適切に無視)扱わなければなりません。特に、ユーザーエージェントは、単一の複数値プロパティ宣言において、サポートされていない構成値だけを選択的に無視し、サポートされている値だけを有効にしてはなりません。いずれかの値が無効(サポートされていない値は必ず無効)とみなされる場合、CSSは宣言全体を無視することを要求します。

不安定および独自拡張機能の実装

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

非実験的な実装

仕様がCandidate Recommendation段階に達すると、非実験的な実装が可能となり、実装者は仕様に従って正しく実装できることを示せるCRレベルの機能について、接頭辞無しの実装を公開すべきです。

CSSの実装間で相互運用性を確立・維持するため、CSSワーキンググループは非実験的なCSSレンダラーに対して、接頭辞無しのCSS機能を公開する前に、実装報告書(必要ならそのテストケースも)をW3Cに提出するよう求めています。W3Cに提出されたテストケースはCSSワーキンググループによるレビューや修正の対象となります。

テストケースや実装報告書の提出方法については、CSSワーキンググループのウェブサイトhttps://www.w3.org/Style/CSS/Test/で案内しています。 質問はpublic-css-testsuite@w3.orgメーリングリストまで。

索引

本仕様で定義される用語

参照によって定義される用語

参考文献

規範的参考文献

[CSS-CASCADE-4]
Elika Etemad; Tab Atkins Jr.. CSSカスケードと継承 レベル4。2022年1月13日。CR。URL: https://www.w3.org/TR/css-cascade-4/
[CSS-CASCADE-6]
Elika Etemad; Miriam Suzanne; Tab Atkins Jr.. CSSカスケードと継承 レベル6。2021年12月21日。WD。URL: https://www.w3.org/TR/css-cascade-6/
[CSS-COLOR-4]
Tab Atkins Jr.; Chris Lilley; Lea Verou. CSSカラーモジュール レベル4。2022年11月1日。CR。URL: https://www.w3.org/TR/css-color-4/
[CSS-NESTING-1]
Tab Atkins Jr.; Adam Argyle. CSSネスティングモジュール。2021年8月31日。WD。URL: https://www.w3.org/TR/css-nesting-1/
[CSS-SYNTAX-3]
Tab Atkins Jr.; Simon Sapin. CSS構文モジュール レベル3。2021年12月24日。CR。URL: https://www.w3.org/TR/css-syntax-3/
[CSS-VALUES-4]
Tab Atkins Jr.; Elika Etemad. CSS値と単位モジュール レベル4。2022年10月19日。WD。URL: https://www.w3.org/TR/css-values-4/
[CSS21]
Bert Bos; 他. カスケーディング・スタイル・シート レベル2改訂1 (CSS 2.1) 仕様書。2011年6月7日。REC。URL: https://www.w3.org/TR/CSS21/
[CSSOM]
Daniel Glazman; Emilio Cobos Álvarez. CSSオブジェクトモデル (CSSOM)。2021年8月26日。WD。URL: https://www.w3.org/TR/cssom-1/
[RFC2119]
S. Bradner. RFCで要求レベルを示すキーワード。1997年3月。Best Current Practice。URL: https://datatracker.ietf.org/doc/html/rfc2119
[SELECTORS4]
Elika Etemad; Tab Atkins Jr.. セレクター レベル4。2022年11月11日。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-CASCADE-5]
Elika Etemad; Miriam Suzanne; Tab Atkins Jr.. CSSカスケードと継承 レベル5。2022年1月13日。CR。URL: https://www.w3.org/TR/css-cascade-5/
[CSS-COLOR-3]
Tantek Çelik; Chris Lilley; David Baron. CSSカラーモジュール レベル3。2022年1月18日。REC。URL: https://www.w3.org/TR/css-color-3/
[CSS-CONDITIONAL-3]
David Baron; Elika Etemad; Chris Lilley. CSS条件付きルールモジュール レベル3。2022年1月13日。CR。URL: https://www.w3.org/TR/css-conditional-3/
[CSS-CONTAIN-3]
Tab Atkins Jr.; Florian Rivoal; Miriam Suzanne. CSSコンテインメントモジュール レベル3。2022年8月18日。WD。URL: https://www.w3.org/TR/css-contain-3/
[CSS-GRID-2]
Tab Atkins Jr.; Elika Etemad; Rossen Atanassov. CSSグリッドレイアウトモジュール レベル2。2020年12月18日。CR。URL: https://www.w3.org/TR/css-grid-2/
[CSS-UI-4]
Florian Rivoal. CSS基本ユーザーインターフェースモジュール レベル4。2021年3月16日。WD。URL: https://www.w3.org/TR/css-ui-4/
[HTML]
Anne van Kesteren; 他. HTML標準。Living Standard。URL: https://html.spec.whatwg.org/multipage/

IDL索引

partial interface CSSStyleRule {
  [SameObject] readonly attribute CSSRuleList cssRules;
  unsigned long insertRule(CSSOMString rule, optional unsigned long index = 0);
  undefined deleteRule(unsigned long index);
};

課題索引

CSSWGは現在、パースの先読みによる影響を検討しており、 その結果として許可される構文を調整する可能性があります。[Issue #7961]
この制限を緩和したいと考えていますが、 :is()&の両方を同時に変更する必要があります。 どちらも意図して同じ基盤の仕組みを使っているためです。 (Issue 7433)
上記の段落はCSSOMアルゴリズムにインライン化される予定です。