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 (谷歌)
Adam Argyle (谷歌)
建议修改此规范:
GitHub 编辑器

摘要

此模块引入了在一个样式规则中嵌套另一个样式规则的功能,子规则的选择器相对于父规则的选择器。这增加了 CSS 样式表的模块化和可维护性。

CSS 是一种用于描述结构化文档(如 HTML 和 XML)在屏幕、纸张等上的呈现语言。

本文件状态

此部分描述了本文件在发布时的状态。当前 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 只需要少量、已知的回溯能力, 这使得更高效的解析算法成为可能, 因此无限回溯在浏览器实现中通常被认为是不可接受的。

2.1. 语法

样式规则的内容现在接受嵌套样式规则at 规则, 以及现有的声明

嵌套样式规则 与非嵌套规则的不同之处在于:

嵌套样式规则的解析的具体细节定义在[CSS-SYNTAX-3]中。

CSS 工作组目前正在探索解析前瞻的后果, 并可能因此调整允许的语法。[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; }
*/

/* & 可以在单个选择器中使用多次 */
.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; }
*/

/* 层叠层的示例用法 */
@layer base {
  html {
    block-size: 100%;

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

/* 层叠层的嵌套示例 */
@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. 嵌套其他 At 规则

除了嵌套样式规则, 本规范还允许在样式规则中嵌套嵌套组规则: 任何其主体包含样式规则的 at 规则都可以嵌套在 样式规则中。

以这种方式嵌套时, 嵌套组规则的内容会被解析为<样式块>而不是<样式表>

具体来说,以下规则可以作为嵌套组规则

这些嵌套组规则的含义和行为与非嵌套时相同, 除非另有规定。

例如,以下条件嵌套是有效的:
/* 属性可以直接使用 */
.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; 
    } 
  } 
*/ 

/* 层叠层嵌套示例 */ 
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 对象 将在其.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. 混合嵌套规则与声明

当样式规则同时包含声明 和嵌套样式规则嵌套条件组规则时, 这三者可以任意混合。 然而,声明和其他规则的相对顺序不会以任何方式保留。

例如, 在以下代码中:
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 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()的行为相同)。

例如,给定以下样式规则:
#a, b { 
  & c { color: blue; } 
} 
.foo c { color: red; } 

然后在如下的 DOM 结构中

<b class=foo> 
  <c>蓝色文本</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()? 一些非浏览器的类似嵌套功能的实现 并没有简化为: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 {...} 

在这里,三个级别的嵌套, 每个列表中有三个选择器, 产生了27个简化后的选择器。 向列表中添加更多选择器, 增加更多的嵌套层次, 或使嵌套规则更复杂 可能会使相对较小的规则 扩展为多兆字节的选择器 (或更多!)。

一些 CSS 工具通过启发式丢弃某些变体 来避免这种问题, 这样它们就不必输出那么多, 但仍然可能是正确的, 但这不是用户代理可用的选项。

通过使用: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 规则中移除index位置的 CSS 规则,移除 CSS 规则

注意: 带有嵌套规则的CSSStyleRule 的序列化 已由[CSSOM]很好地定义, 通过序列化 CSS 规则

注意:嵌套样式规则选择器可以以什么开头的限制 在插入 CSS 规则步骤 5 中被视为“CSS 施加的约束” (当调用插入 CSS 规则时适用,不仅仅是CSSStyleRule 本身)。

当设置selectorText时, 如果CSSStyleRule嵌套样式规则, 且返回的选择器组 以选择器开头,该选择器以标识符或函数 token 开头, 则不执行任何操作并返回。

上述段落将内联到 CSSOM 算法中, 而不是被猴子补丁。

符合性

文档约定

符合性要求使用描述性断言和 RFC 2119 术语的组合表达。“必须(MUST)”、“不得(MUST NOT)”、“要求(REQUIRED)”、“应当(SHALL)”、“不应当(SHALL NOT)”、“应该(SHOULD)”、“不应该(SHOULD NOT)”、“建议(RECOMMENDED)”、“可以(MAY)”和“可选(OPTIONAL)”这些关键字在本文件的规范部分应按照 RFC 2119 中的解释进行理解。为了易读性,这些词在本规范中不全部大写。

除明确标记为非规范性的部分、示例和注释外,本规范的所有文本都是规范性的。[RFC2119]

本规范中的示例以“例如”一词引入,或通过 class="example" 与规范文本分开,如下所示:

这是一个信息性示例。

信息性注释以“注释”一词开头,并通过 class="note" 与规范文本分开,如下所示:

注释:这是一个信息性注释。

建议部分是规范性部分,以引起特别注意为目的,并通过 <strong class="advisement"> 与其他规范性文本分开,如下所示: UA 必须提供可访问的替代方案。

符合性类别

对本规范的符合性 定义为三个符合性类别:

样式表
CSS 样式表
渲染器
UA,解释样式表的语义并渲染使用它们的文档。
创作工具
UA,用于编写样式表的工具。

如果样式表中使用的所有语法语句都根据本模块定义的通用 CSS 语法和每个功能定义的单个语法有效,则该样式表符合本规范。

如果渲染器除了按照适当的规范解释样式表外,还能通过正确解析它们并相应地渲染文档来支持本规范定义的所有功能,则该渲染器符合本规范。然而,因设备限制导致 UA 无法正确渲染文档并不会使 UA 不符合规范。(例如,UA 不要求在单色显示器上渲染颜色。)

如果创作工具编写的样式表在语法上符合通用 CSS 语法和本模块中每个功能的单个语法,并且满足本模块中描述的样式表的所有其他符合性要求,则该创作工具符合本规范。

部分实现

为了让作者利用前向兼容的解析规则来分配回退值,CSS 渲染器必须将任何不支持的 at 规则、属性、属性值、关键字和其他语法结构视为无效,并根据需要忽略。特别是,用户代理不得在一个多值属性声明中选择性忽略不支持的值并保留支持的值:如果任何值被视为无效(因为不支持的值必须被视为无效),CSS 要求忽略整个声明。

不稳定和专有功能的实现

为了避免与未来稳定的 CSS 功能发生冲突,CSSWG 建议遵循最佳实践,以实现不稳定的功能和 CSS 的专有扩展

非实验性实现

一旦规范达到候选推荐阶段,非实验性实现是可能的,实施者应发布任何 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 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. 21 December 2021. WD. URL: https://www.w3.org/TR/css-cascade-6/
[CSS-COLOR-4]
Tab Atkins Jr.; Chris Lilley; Lea Verou. CSS Color Module Level 4. 1 November 2022. CR. URL: https://www.w3.org/TR/css-color-4/
[CSS-NESTING-1]
Tab Atkins Jr.; Adam Argyle. CSS Nesting Module. 31 August 2021. WD. URL: https://www.w3.org/TR/css-nesting-1/
[CSS-SYNTAX-3]
Tab Atkins Jr.; Simon Sapin. CSS Syntax Module Level 3. 24 December 2021. CR. URL: https://www.w3.org/TR/css-syntax-3/
[CSS-VALUES-4]
Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 4. 19 October 2022. WD. URL: https://www.w3.org/TR/css-values-4/
[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/CSS21/
[CSSOM]
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
[SELECTORS4]
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-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-COLOR-3]
Tantek Çelik; Chris Lilley; David Baron. CSS Color Module Level 3. 18 January 2022. REC. URL: https://www.w3.org/TR/css-color-3/
[CSS-CONDITIONAL-3]
David Baron; Elika Etemad; Chris Lilley. CSS Conditional Rules Module Level 3. 13 January 2022. CR. URL: https://www.w3.org/TR/css-conditional-3/
[CSS-CONTAIN-3]
Tab Atkins Jr.; Florian Rivoal; Miriam Suzanne. CSS Containment Module Level 3. 18 August 2022. WD. URL: https://www.w3.org/TR/css-contain-3/
[CSS-GRID-2]
Tab Atkins Jr.; Elika Etemad; Rossen Atanassov. CSS Grid Layout Module Level 2. 18 December 2020. CR. URL: https://www.w3.org/TR/css-grid-2/
[CSS-UI-4]
Florian Rivoal. CSS Basic User Interface Module Level 4. 16 March 2021. WD. URL: https://www.w3.org/TR/css-ui-4/
[HTML]
Anne van Kesteren; et al. HTML Standard. 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目前正在探索解析前瞻的影响, 可能因此调整允许的语法。 [问题 #7961]
我们希望放宽此限制, 但需要同时对:is()&进行调整, 因为它们基于相同的底层机制。 (问题 7433)
上述段落将被内联到CSSOM算法中, 而不是通过补丁处理。