选择器第 4 级 (Selectors Level 4)

W3C 工作草案

关于此文档的更多细节
此版本
https://w3org.cn/TR/2026/WD-selectors-4-20260122/
最新发布版本
https://w3org.cn/TR/selectors-4/
编辑草案
https://drafts.csswg.org/selectors/
历史版本
历史
https://w3org.cn/standards/history/selectors-4/
反馈
CSS 工作组问题仓库
文档内联
编辑
Elika J. Etemad / fantasai (Apple)
Tab Atkins Jr. (Google)
前任编辑
Tantek Çelik
Daniel Glazman
Ian Hickson
Peter Linss
John Williams
建议编辑此规范
GitHub 编辑器
测试套件
https://wpt.fyi/results/css/selectors/

摘要

选择器是用于匹配树状结构中元素的模式,因此它是可用于选择文档中节点的多种技术之一。选择器已针对 HTML 和 XML 的使用进行了优化,并设计为可用于性能关键型代码中。它们是 CSS (Cascading Style Sheets) 的核心组成部分,CSS 使用选择器将样式属性绑定到文档中的元素。选择器第 4 级描述了 [SELECT] 中已有的选择器,并进一步引入了 CSS 和其他可能需要它们的语言所需要的新选择器。

CSS 是一种用于描述结构化文档(如 HTML 和 XML)在屏幕、纸张等介质上渲染方式的语言。

关于本文档

本节描述了本文件发布时的状态。当前 W3C 出版物列表及本技术报告的最新修订版可在 W3C 标准和草案索引中找到。

本文件由 CSS 工作组推荐标准轨道发布为工作草案。发布为工作草案并不意味着 W3C 及其成员的认可。

这是一个草案文档,可能随时会被其他文档更新、替换或废弃。将其作为进展中的工作之外的任何内容进行引用是不恰当的。

请通过 在 GitHub 上提交问题(首选)来提供反馈,并在标题中包含规范代码“selectors”,如下所示:“[selectors] …意见摘要…”。所有问题和意见都已存档。或者,可以将反馈发送至(已存档的)公开邮件列表 www-style@w3.org

本文件受 2025 年 8 月 18 日 W3C 流程文件的管辖。

本文档由在一个受 W3C 专利政策约束下运作的组织制作。W3C 维护着一份与该组织交付成果相关的专利披露公开列表;该页面还包含了披露专利的说明。任何个人如果确实获知其认为包含必要权利要求 (Essential Claim) 的专利,必须根据 W3C 专利政策第 6 节披露该信息。

以下功能存在风险,可能会在 CR 期间被删除:

“风险(At-risk)”是 W3C 流程中的术语,并不一定意味着该特性面临被删除或推迟的危险。这表示工作组认为该特性可能难以及时实现互操作,将其标记为此类允许工作组在转向“建议推荐标准(Proposed Rec)”阶段时,在必要的情况下删除该特性,而无需先发布一个不包含该特性的新“候选推荐标准(Candidate Rec)”。

1. 介绍

本节不具有规范性。

测试

本节为非规范性内容,无需测试。


选择器是一个布尔谓词,它接收树结构中的一个元素,并测试该元素是否与选择器匹配。

这些表达式可用于许多场景:

选择器第 1、2 和 3 级分别定义为 CSS1CSS2.1选择器第 3 级规范中定义的功能子集。本模块定义选择器第 4 级。

1.1. 模块交互

测试

本节无需测试。


本模块替换了 [SELECT][CSS21] 中为 CSS 定义的选择器定义,并扩展了该集合。

在渲染树中定义抽象元素的伪元素选择器不属于本规范:此处描述了它们的通用语法,但由于它们与渲染模型联系紧密且与其他用途(如 DOM 查询)无关,因此它们将在其他模块中定义。

2. 选择器概述

本节是非规范性的,因为它仅总结了以下章节。

测试

本节为非规范性内容,无需测试。


选择器代表一种结构。该结构可以用作条件(例如在 CSS 规则中),确定选择器在文档树中匹配哪些元素;也可以用作与该结构对应的 HTML 或 XML 片段的平面描述。

选择器的范围可以从简单的元素名称到丰富的上下文表示。

下表总结了选择器语法

Pattern表示级别
* 任意元素§ 5.2 通用选择器 2
E E 类型的元素§ 5.1 类型(标签名)选择器 1
E:not(s1, s2, …) 一个与复合选择器 s1复合选择器 s2 均不匹配的 E 元素§ 4.3 否定(不匹配)伪类::not() 3/4
E:is(s1, s2, …) 一个与复合选择器 s1 和/或 复合选择器 s2 匹配的 E 元素§ 4.2 匹配任意伪类::is() 4
E:where(s1, s2, …) 一个与复合选择器 s1 和/或 复合选择器 s2 匹配但不对特异性做出贡献的 E 元素。§ 4.4 特异性调整伪类::where() 4
E:has(rs1, rs2, …) 一个 E 元素,当以 E 作为锚元素进行评估时,如果存在匹配相对选择器 rs1rs2 的元素§ 4.5 关系伪类::has() 4
E.warning 一个属于 warning 类的 E 元素(文档语言指定了类是如何确定的)。§ 6.6 类选择器 1
E#myid 一个 ID 等于 myid 的 E 元素。§ 6.7 ID 选择器 1
E[foo] 一个具有 foo 属性的 E 元素§ 6.1 属性存在与值选择器 2
E[foo="bar"] 一个 foo 属性值完全等于 bar 的 E 元素§ 6.1 属性存在与值选择器 2
E[foo="bar" i] 一个 foo 属性值完全等于 bar 的任意(ASCII 范围)大小写排列的 E 元素§ 6.3 大小写敏感性 4
E[foo="bar" s] 一个 foo 属性值 bar 完全相同的 E 元素§ 6.3 大小写敏感性 4
E[foo~="bar"] 一个 foo 属性值为以空格分隔的值列表,其中之一完全等于 bar 的 E 元素§ 6.1 属性存在与值选择器 2
E[foo^="bar"] 一个 foo 属性值以字符串 bar 开头的 E 元素§ 6.2 子字符串匹配属性选择器 3
E[foo$="bar"] 一个 foo 属性值以字符串 bar 结尾的 E 元素§ 6.2 子字符串匹配属性选择器 3
E[foo*="bar"] 一个 foo 属性值包含子字符串 bar 的 E 元素§ 6.2 子字符串匹配属性选择器 3
E[foo|="en"] 一个 foo 属性值为以连字符分隔的值列表,并以 en 开头的 E 元素§ 6.1 属性存在与值选择器 2
E:dir(ltr) 一个具有从左到右方向性的 E 类型元素(文档语言指定了方向性是如何确定的)§ 7.1 方向性伪类::dir() 4
E:lang(zh, "*-hant") 一个标记为中文(任何方言或书写系统)或以繁体中文字符书写的 E 类型元素§ 7.2 语言伪类::lang() 2/4
E:any-link 一个作为超链接源锚点的 E 元素§ 8.1 超链接伪类::any-link 4
E:link 一个作为超链接源锚点且目标尚未被访问过的 E 元素§ 8.2 链接历史伪类::link 和 :visited 1
E:visited 一个作为超链接源锚点且目标已被访问过的 E 元素§ 8.2 链接历史伪类::link 和 :visited 1
E:target 一个作为当前 URL 目标的 E 元素§ 8.3 目标伪类::target 3
E:scope 一个作为作用域根的 E 元素§ 8.4 参考元素伪类::scope 4
E:active 一个处于激活状态的 E 元素§ 9.2 激活伪类::active 1
E:hover 一个处于光标之下,或其后代处于光标之下的 E 元素§ 9.1 指针悬停伪类::hover 2
E:focus 一个具有用户输入焦点的 E 元素§ 9.3 输入焦点伪类::focus 2
E:focus-within 一个具有用户输入焦点或包含具有输入焦点的元素的 E 元素。§ 9.5 焦点容器伪类::focus-within 4
E:focus-visible 一个具有用户输入焦点,且 UA 已确定该元素应绘制焦点环或其他指示符的 E 元素§ 9.4 焦点指示伪类::focus-visible 4
E:enabled
E:disabled
分别是已启用或已禁用的用户界面元素 E§ 12.1.1 :enabled 和 :disabled 伪类 3
E:read-write
E:read-only
分别是用户可修改或不可修改的用户界面元素 E§ 12.1.2 可变性伪类::read-only 和 :read-write 3-UI/4
E:placeholder-shown 当前显示占位符文本的输入控件§ 12.1.3 占位符显示伪类::placeholder-shown 3-UI/4
E:default 作为一组相关选项中默认项的用户界面元素 E§ 12.1.5 默认选项伪类::default 3-UI/4
E:checked
E:unchecked
E:indeterminate
处于选中(例如单选按钮或复选框)、未选中或不确定状态(既非选中也非未选中)的用户界面元素 E§ 12.2 输入值状态 3
E:valid
E:invalid
符合或不符合其数据验证语义的用户输入元素 E§ 12.3.1 有效性伪类::valid 和 :invalid 3-UI/4
E:in-range
E:out-of-range
值在范围内/超出范围的用户输入元素 E§ 12.3.2 范围伪类::in-range 和 :out-of-range 3-UI/4
E:required
E:optional
需要/不需要输入的用户输入元素 E§ 12.3.3 可选性伪类::required 和 :optional 3-UI/4
E:user-invalid 输入错误(无效、超出范围、省略但必需)的用户修改过且用户输入元素 E§ 12.3.4 用户交互伪类::user-valid 和 :user-invalid 4
E:root 作为文档根的 E 元素§ 13.1 :root 伪类 3
E:empty 没有子节点(既没有元素也没有文本,可能除空白字符外)的 E 元素§ 13.2 :empty 伪类 3
E:nth-child(n [of S]?) 一个 E 元素,它是其父元素的第 n 个匹配 S 的子元素§ 13.3.1 :nth-child() 伪类 3/4
E:nth-last-child(n [of S]?) 一个 E 元素,它是其父元素的第 n 个匹配 S 的子元素,从最后一个开始倒数§ 13.3.2 :nth-last-child() 伪类 3/4
E:first-child 一个 E 元素,它是其父元素的第一个子元素§ 13.3.3 :first-child 伪类 2
E:last-child 一个 E 元素,它是其父元素的最后一个子元素§ 13.3.4 :last-child 伪类 3
E:only-child 一个 E 元素,它是其父元素的唯一子元素§ 13.3.5 :only-child 伪类 3
E:nth-of-type(n) 一个 E 元素,它是其同类型元素中的第 n 个同胞§ 13.4.1 :nth-of-type() 伪类 3
E:nth-last-of-type(n) 一个 E 元素,它是其同类型元素中的第 n 个同胞,从最后一个开始倒数§ 13.4.2 :nth-last-of-type() 伪类 3
E:first-of-type 一个 E 元素,它是其同类型元素中的第一个同胞§ 13.4.3 :first-of-type 伪类 3
E:last-of-type 一个 E 元素,它是其同类型元素中的最后一个同胞§ 13.4.4 :last-of-type 伪类 3
E:only-of-type 一个 E 元素,它是其同类型元素中的唯一同胞§ 13.4.5 :only-of-type 伪类 3
E F 作为 E 元素后代的 F 元素§ 14.1 后代组合子 ( ) 1
E > F 作为 E 元素子代的 F 元素§ 14.2 子代组合子 (>) 2
E + F 紧跟在 E 元素后的 F 元素§ 14.3 相邻兄弟组合子 (+) 2
E ~ F 在 E 元素后的 F 元素§ 14.4 后续兄弟组合子 (~) 3

注意: 一些第 4 级选择器(上面标注为 "3-UI")在 [CSS3UI] 中引入。

测试

与任何章节无关的测试


3. 选择器语法与结构

3.1. 结构与术语

选择器(selector)表示树结构中特定模式的一个或多个元素。术语选择器可以指代简单选择器复合选择器复杂选择器选择器列表选择器的主体(subject of a selector)是该选择器所定义的目标元素;即任何匹配选择器的元素。

简单选择器(simple selector)是对元素的一个单一条件。类型选择器通用选择器属性选择器类选择器ID 选择器伪类都是简单选择器。(在选择器语法中,它由<simple-selector>表示。)当给定的元素满足本规范定义并符合文档语言的描述时,称该元素匹配简单选择器

复合选择器(compound selector)是一系列未被组合符分隔的简单选择器,表示对单个元素的一组同时满足的条件。如果它包含类型选择器通用选择器,则该选择器必须位于序列的首位。序列中只允许出现一个类型选择器或通用选择器。(复合选择器在选择器语法中由<compound-selector>表示。)当给定的元素匹配复合选择器中的所有简单选择器时,称该元素匹配该复合选择器。

注:由于空白字符表示后代组合符,因此复合选择器中的简单选择器之间不允许有空白字符。

伪复合选择器(pseudo-compound selector)是一个伪元素选择器,其后可选地跟随额外的伪类选择器,并在其前可选地由复合选择器或其他伪复合选择器作为前导,中间没有任何组合符。(伪复合选择器在选择器语法中由<pseudo-compound-selector>表示。)当伪元素具有指定的伪元素名称、匹配任何伪类表示的额外条件,且具有由相邻前导选择器所表示的始发元素(originating element)时,称该伪元素匹配伪复合选择器。如果没有相邻的前导选择器,则假设为通用选择器。(例如,.foo ::before 等同于 .foo *::before,但与 .foo::before 不同。)

例如,在 .foo::before:hover 中,.foo 是一个复合选择器,而 ::before:hover 是一个伪复合选择器。然而,在 .foo::before::marker 中,::before::marker 是独立的伪复合选择器

注:伪复合选择器不是复合选择器,不能用于仅期望复合选择器的地方。伪复合选择器的行为就像它们自身携带了一个组合符,用以表达它们与始发元素之间的关系,正如 > 组合符表达与父元素的关系一样。

组合符(combinator)是两个由复合选择器分别代表的元素之间的关系条件。Selectors Level 4 中的组合符包括:后代组合符(空格)、子代组合符(U+003E, >)、相邻兄弟组合符(U+002B, +)以及后续兄弟组合符(U+007E, ~)。当两个元素之间的关系条件成立时,称这两个元素匹配组合符

复杂选择器(complex selector)是由一个或多个复合选择器和/或伪复合选择器组成的序列,其中复合选择器组合符分隔。它表示一组在特定关系下的元素集合,这些关系由其组合符描述。(复杂选择器在选择器语法中由<complex-selector>表示。)当给定的元素或伪元素匹配序列中的最后一个复合选择器/伪复合选择器,且序列中每一个前导单元也都匹配相应的元素或伪元素,并且连续单元之间的正确关系符合分隔它们的组合符表达(对于伪复合选择器,则是正确的始发元素关系)时,称该元素或伪元素匹配复杂选择器

例如,.foo.bar 匹配同时具有 "foo" 和 "bar" 类的元素。

.ancestor > .foo.bar 匹配上述元素的一个子集:仅匹配那些父元素(由 > 组合符指示)具有 "ancestor" 类的元素。

.foo.bar::before 匹配一个 ::before 伪元素,其始发元素匹配 .foo.bar

简单/复合/复杂选择器列表(list of simple/compound/complex selectors)是由逗号分隔的简单复合复杂选择器的列表。当类型无关紧要或已在上下文语境中说明时,它也简称为选择器列表(selector list);如果类型重要但未说明,则默认为复杂选择器列表。(关于选择器列表及其正式语法的各种 <*-selector-list> 生成规则,请参阅 § 4.1 选择器列表。)当给定的元素匹配该选择器列表中至少一个选择器时,称该元素匹配该选择器列表。

3.2. 数据模型

选择器是针对 DOM 等元素树进行评估的。[DOM] 在本规范中,这可能被称为“文档树”或“源文档”。

每个元素可以包含以下五个属性中的任何一个,这些属性可以被选择,所有这些属性都作为字符串进行匹配:

许多选择器取决于文档语言(即文档树的语言和语义)和/或宿主语言(即使用选择器语法的语言)的语义。例如,:lang() 选择器依赖于文档语言(例如 HTML)来定义元素如何与语言相关联。作为另一个稍有不同的例子,::first-line 伪元素依赖于宿主语言(例如 CSS)来定义 ::first-line 伪元素表示什么以及它能做什么。

3.2.1. 无特征元素

测试

虽然个别元素可能缺乏上述任何特征,但某些元素是无特征的(featureless)。无特征元素完全不匹配任何选择器,除非:

如果一个选择器原本会匹配一个无特征元素,但因默认命名空间[CSS-NAMESPACES-3]的存在而无法匹配(因为无特征元素除非另有定义,否则没有命名空间),则默认命名空间不会阻止该匹配。

例如,影子宿主(shadow host)在影子树中是无特征的,除了 :host:host-context()(或包含它们的组合,如 :is(:host, :root))之外,任何伪类都无法匹配它。

:not(.foo:host) 这样的逻辑组合永远不会匹配宿主元素(即使它没有 "foo" 类),因为 .foo:host 中的并非所有简单选择器都被允许匹配该影子宿主

类似地,:not(:host > .foo) 也永远不会匹配影子宿主,尽管影子宿主确实*不是*其自身的后代且不包含 "foo" 类,这是因为复杂选择器参数的主体(.foo)不允许匹配影子宿主

通常,如果不显式使用其被允许匹配的简单选择器,就无法匹配无特征元素,以避免意外选中这些元素(它们被刻意设计为容易被忽略)。例如,* 永远不会匹配无特征元素。

上述关于 :has() 的规则工作原理类似。即使影子宿主包含一个 .foo 后代,:has(.foo) 也不会匹配它,因为其余的复合选择器(空的)不包含可以匹配宿主的简单选择器。你必须编写 :host:has(.foo) 才能匹配宿主元素。

3.3. 作用域选择器

一些宿主应用程序可以选择将选择器作用域(scope)限定为文档的特定子树或片段。作用域子树的根被称为作用域根(scoping root)。

当选择器被作用域限定(scoped)时,它仅在元素是作用域根的后代时才匹配该元素。(选择器的其余部分可以不受限制地匹配;只有最终匹配的元素必须在作用域内。)

例如,在 [DOM] 中定义的 querySelector() 方法允许开发者相对于调用该方法的元素来评估一个作用域限定的选择器

因此,类似 widget.querySelector("a") 的调用将仅查找 widget 元素内部的 a 元素,而忽略文档中散布的其他 a 元素。

3.4. 相对选择器

某些上下文可能接受相对选择器(relative selectors),这是表示相对于一个或多个相对选择器锚元素的元素的简写。相对选择器以组合符开头,并在选择器开头隐含代表锚元素的选择器。(如果没有组合符,则隐含后代组合符。)

相对选择器在选择器语法中由<relative-selector>表示,其列表由 <relative-selector-list> 表示。

3.5. 伪类

伪类(Pseudo-classes)是允许根据文档树之外的信息进行选择的简单选择器,或者使用其他简单选择器表达起来可能很笨拙或不可能的选择。它们也可以是动态的,即元素在用户与文档交互时可以获得或失去伪类,而无需更改文档本身。伪类不会出现在文档源码或文档树中,也不会修改它们。

伪类的语法由 ":"(U+003A 冒号)后跟作为 CSS 标识符的伪类名称组成;在函数型伪类(functional pseudo-class)的情况下,则是一对包含其参数的括号。

例如,:valid 是一个普通伪类,:lang() 是一个函数型伪类

像所有 CSS 关键字一样,伪类名称是ASCII 大小写不敏感的。冒号与伪类名称之间不允许有空白字符,而且按照 CSS 常规语法,函数型伪类的名称与其左括号之间也不允许有空白(它们共同构成一个 CSS 函数记号)。同样按照惯例,除非另有说明,否则函数型伪类的括号内参数周围允许存在空白字符

像其他简单选择器一样,伪类允许出现在选择器中包含的所有复合选择器内,并且如果存在类型选择器通用选择器,必须跟在它们后面。

注:有些伪类是互斥的(使得包含它们的复合选择器虽然有效,但永远不会匹配任何内容),而其他伪类则可以同时应用于同一个元素。

3.6. 伪元素

测试

与某些伪类表示文档树中不存在的额外状态信息类似,伪元素(pseudo-element)表示文档树中不直接存在的元素。它们用于创建超出文档树本身提供的关于文档树的抽象。例如,伪元素可用于选择文档中不对应文档语言元素的部分(包括不与元素边界对齐或不符合其树结构的部分);表示文档树中不存在的内容,或文档树的替代投影;或依赖于样式、布局、用户交互以及其他未在文档树中反映的过程所提供的信息。

例如,文档语言不提供访问元素内容的首字母或首行的机制,但存在伪元素::first-letter::first-line),允许对这些内容进行样式化。特别注意,对于 ::first-line 的情况,伪元素表示的内容部分取决于无法从文档树推断出的布局信息。

伪元素还可以表示源文档中根本不存在的内容,例如 ::before::after 伪元素,它们允许在任何元素的内容之前或之后插入额外内容。

伪类一样,伪元素不会出现在文档源码或文档树中,也不会修改它们。相应地,它们也不会影响结构伪类或其他涉及其始发元素及其树的选择器的解释。

宿主语言定义了哪些伪元素存在、它们的类型及其能力。CSS 中存在的伪元素定义在 [CSS21](Level 2)、[SELECT](Level 3)和 [CSS-PSEUDO-4](Level 4)中。

3.6.1. 语法

伪元素的语法是 "::"(两个 U+003A 冒号字符)后跟作为标识符的伪元素名称;在函数型伪元素的情况下,则是一对包含其参数的括号。伪元素名称是ASCII 大小写不敏感的。两个冒号之间,或冒号与名称之间不允许有空白字符

由于 CSS Level 1CSS Level 2 为伪元素和伪类混用了单冒号语法,因此用户代理必须同时接受 Level 1 和 Level 2 伪元素的旧版单冒号表示法(::before::after::first-line::first-letter)。这种兼容性表示法不适用于任何其他伪元素。然而,由于该语法已弃用,作者应为这些伪元素使用 Level 3+ 的双冒号语法。

伪元素无特征的,因此不能被任何其他选择器匹配。

3.6.2. 绑定到文档树

伪元素在树中并不独立存在:它们总是绑定到页面上的另一个元素,称为其始发元素。在语法上,伪元素紧跟在代表其始发元素复合选择器之后。如果省略此复合选择器,则默认为通用选择器 *

例如,在选择器 div a::before 中,被选择器匹配的 a 元素就是附加在其上的 ::before 伪元素的始发元素

选择器 ::first-line 等同于 *::first-line,它选择文档中每个元素上的 ::first-line 伪元素。

当选择器中遇到伪元素时,伪元素之前的部分选择该伪元素的始发元素;其后的部分(如果有)则应用于伪元素本身。(见下文。)

3.6.3. 伪元素的伪类化

某些伪元素可以紧跟任何伪类组合,这种情况下,伪元素仅在处于相应状态时才被表示。本规范允许任何伪元素后跟任何逻辑组合伪类用户操作伪类的组合。其他规范可能允许将额外的伪类附加到特定的伪元素。未明确允许的组合是无效选择器

注:逻辑组合伪类将其位置的选择器有效性限制传递给它们的参数。

例如,由于 :hover 伪类规定它可以应用于任何伪元素,::first-line:hover 将在第一行被悬停时匹配。然而,由于 :focus::first-line 都没有定义 :focus 可以应用于 ::first-line,因此选择器 ::first-line:focus 永远不会匹配任何内容。

请注意,::first-line:hover:hover::first-line 非常不同,后者匹配任何被悬停的始发元素的第一行!例如,:hover::first-line 也会在段落的第二行被悬停时匹配该段落的第一行,而 ::first-line:hover 仅在第一行本身被悬停时匹配。

3.6.4. 子伪元素

一些伪元素能够成为其他伪元素始发元素,这些伪元素被定义为该始发伪元素(originating pseudo-element)的子伪元素(sub-pseudo-elements)。例如,当 ::before 被赋予 list-item 显示类型时,它成为其 ::before::marker 子伪元素始发伪元素

在需要消除歧义的情况下,术语最终始发元素(ultimate originating element)指代伪元素所源自的真实(非伪)元素。

除非相应的子伪元素在另一规范中被明确定义存在,否则伪元素选择器在复合到另一个伪元素选择器时是无效的。因此,例如,::before::before 是一个无效选择器,但 ::before::marker 是有效的(在支持 ::before::marker 子伪元素的实现中)。

3.6.5. 内部结构

一些伪元素被定义为具有内部结构。这些伪元素后可跟随子代/后代组合符以表示这些关系。包含伪元素后组合符的选择器在其他情况下是无效的。

例如,::first-letter + span::first-letter em 是无效选择器。然而,如果定义了一个新的 ::shadow 伪元素具有内部结构,那么 ::shadow > p 将是一个有效的选择器。

注:未来的规范可能会扩展现有伪元素的能力,因此某些当前无效的选择器(例如 ::first-line :any-link)在未来可能会变得有效。

此类伪元素的子元素也可以同时是其他元素的子元素。然而,至少在 CSS 中,它们的渲染必须定义为维持框树(box tree)的树结构。

3.7. 字符与大小写敏感性

测试

所有选择器语法均为 ASCII 大小写不敏感(即 [a-z] 和 [A-Z] 等效),不受选择器控制的部分除外:具体而言,文档语言元素名称、属性名称和属性值的大小写敏感性取决于文档语言本身。

例如,在 HTML 中,元素和属性名称是 ASCII 大小写不敏感的,但在 XML 中,它们是大小写敏感的。

命名空间前缀的大小写敏感性定义在 [CSS3NAMESPACE] 中。语言范围的大小写敏感性定义在 :lang() 章节中。

空格在选择器中由代码点 SPACE (U+0020)、TAB (U+0009)、LINE FEED (U+000A)、CARRIAGE RETURN (U+000D) 和 FORM FEED (U+000C) 组成。其他类空格代码点,如 EM SPACE (U+2003) 和 IDEOGRAPHIC SPACE (U+3000),绝不被视为语法上的空格。

选择器中的代码点可以根据与 CSS 相同的转义规则使用反斜杠进行转义。[CSS21] 请注意,转义一个代码点会“抵消”其在选择器中可能具有的任何特殊含义。例如,选择器 #foo>a 包含一个组合符,但 #foo\>a 则是选择一个 id 为 foo>a 的元素。

3.8. 声明命名空间前缀

某些选择器支持命名空间前缀。命名空间前缀的声明机制应由使用选择器的语言来指定。如果该语言没有指定命名空间前缀声明机制,则不声明任何前缀。在 CSS 中,命名空间前缀是通过 @namespace 规则声明的。[CSS3NAMESPACE]

3.9. 无效选择器和错误处理

测试

用户代理必须遵守处理无效选择器的规则

注意:遵循 CSS 向前兼容的解析原则,用户代理必须将任何其不支持的伪类、伪元素、组合符或其他语法结构视为无效。参见 部分实现

无效选择器表示且因此匹配任何内容。

3.10. 遗留别名

某些选择器具有遗留选择器别名。这是一种名称,在解析时会转换为标准名称(因此不会在表示该选择器的任何对象模型中出现)。

4. 逻辑组合

测试

选择器逻辑可以通过复合(逻辑与)、选择器列表(逻辑或)以及逻辑组合伪类 :is():where():not() 来操作。逻辑组合伪类允许出现在任何允许其他伪类的地方,但会将任何限制传递给它们的参数。(例如,如果只允许复合选择器,那么在 :is() 中只有复合选择器是有效的。)

注意:由于在 :is():where() 内部,无效参数会被丢弃而不会使伪类本身无效,因此因上下文限制而失效的选择器参数同样不会使 :is() 伪类本身失效。

4.1. 选择器列表

逗号分隔的选择器列表表示选择器列表中每个单独选择器所选元素集合的并集。(逗号为 U+002C。)例如,在 CSS 中,当多个选择器共享相同的声明时,可以将它们组合成一个逗号分隔的列表。逗号前后可以出现空格。

CSS 示例:在此示例中,我们将三个具有相同声明的规则压缩为一个。因此,
h1 { font-family: sans-serif }
h2 { font-family: sans-serif }
h3 { font-family: sans-serif }

等同于

h1, h2, h3 { font-family: sans-serif }

警告:此示例中的等价性成立,因为所有选择器都是有效选择器。如果这些选择器中只有一个是无效的,则整个选择器列表都将无效。这将使所有三个标题元素的规则无效,而在前者的情况下,三个单独标题规则中只有一个会失效。

无效 CSS 示例
h1 { font-family: sans-serif }
h2..foo { font-family: sans-serif }
h3 { font-family: sans-serif }

并不等同于

h1, h2..foo, h3 { font-family: sans-serif } 

因为上述选择器(h1, h2..foo, h3)完全无效,整个样式规则被丢弃。(当选择器未分组时,只有 h2..foo 的规则被丢弃。)

4.2. 匹配任意伪类::is()

测试

匹配任意伪类 :is() 是一个功能性伪类,接受一个 <forgiving-selector-list> 作为其唯一参数。

如果参数在解析后是一个空列表,则该伪类有效但不匹配任何内容。否则,该伪类匹配任何与列表中任一选择器匹配的元素。

注意::is() 伪类的特指度由其特指度最高的参数的特指度所取代。因此,使用 :is() 编写的选择器不一定与不使用 :is() 编写的等效选择器具有相同的特指度。例如,如果我们有 :is(ul, ol, .list) > [hidden]ul > [hidden], ol > [hidden], .list > [hidden],一个 ol[hidden] 子元素与第一个选择器匹配的特指度为 (0,2,0),而与第二个选择器匹配的特指度为 (0,1,1)。参见 § 15 计算选择器的特指度

伪元素不能由匹配任意伪类表示;它们在 :is() 中是无效的。

默认命名空间声明不会影响 :is() 伪类内表示选择器主体复合选择器,除非该复合选择器包含显式的通用选择器类型选择器

例如,以下选择器匹配任何被悬停或聚焦的元素,无论其命名空间如何。特别地,它不局限于仅匹配默认命名空间中被悬停或聚焦的元素。
*|*:is(:hover, :focus) 

然而,以下选择器仅代表默认命名空间中被悬停或聚焦的元素,因为它在 :is() 表示法中使用了显式的通用选择器

*|*:is(*:hover, *:focus) 

由于本规范的先前草案使用了名称 :matches() 作为此伪类,用户代理如果为了向后兼容性需要,可以额外实现此过时名称作为 :is()遗留选择器别名

4.3. 否定(匹配无)伪类::not()

测试

否定伪类 :not() 是一个功能性伪类,接受一个 <complex-real-selector-list> 作为参数。它代表不被其参数所表示的元素。

注意:在选择器级别 3 中,:not() 的参数仅允许单个简单选择器

注意::not() 伪类的特指度被其参数中特指度最高的选择器的特指度所取代;因此它的行为与 :not(:is(argument)) 完全相同。参见 § 15 计算选择器的特指度

伪元素不能由否定伪类表示;它们在 :not() 中是无效的。

例如,以下选择器匹配 HTML 文档中所有未禁用的 button 元素。
button:not([DISABLED]) 

以下选择器表示除 FOO 元素之外的所有元素。

*:not(FOO)

以下复合选择器表示除链接之外的所有 HTML 元素。

html|*:not(:link):not(:visited)

:is() 一样,默认命名空间声明不会影响 :not() 伪类内表示选择器主体复合选择器,除非该复合选择器包含显式的通用选择器类型选择器。(示例参见 :is()。)

注意::not() 伪类允许书写无用的选择器。例如 :not(*|*),它不代表任何元素,或者 div:not(span),它等同于 div 但具有更高的特指度。

4.4. 特指度调整伪类::where()

测试

特指度调整伪类 :where() 是一个功能性伪类,具有与 :is() 相同的语法和功能。与 :is() 不同,:where() 伪类及其任何参数都不对选择器的特指度做出贡献——其特指度始终为零。

这对于在选择器中引入过滤器同时保持相关的样式声明易于覆盖非常有用。

以下是一个常见的示例,特指度启发式算法无法满足作者的期望
a:not(:hover) {
  text-decoration: none;
}

nav a {
  /* Has no effect */
  text-decoration: underline;
}

然而,通过使用 :where(),作者可以显式声明其意图

a:where(:not(:hover)) {
  text-decoration: none;
}

nav a {
  /* Works now! */
  text-decoration: underline;
}

注意:未来级别的选择器可能会引入一个附加参数,以显式设置该伪类实例的特指度。

4.5. 关系伪类::has()

测试

关系伪类 :has() 是一个功能性伪类,接受一个 <relative-selector-list> 作为参数。如果任何相对选择器锚定于此元素时匹配至少一个元素,则它表示该元素。

:has() 伪类不能嵌套;:has():has() 内部无效。此外,除非明确定义为 :has-allowed 伪元素,否则伪元素:has() 中不是有效选择器。(本规范未定义任何 :has-allowed 伪元素,但其他规范可能会定义。)

注意:伪元素通常被排除在 :has() 之外,因为它们中的许多是根据其祖先的样式有条件地存在的,因此允许通过 :has() 查询它们会引入循环。

注意:由于 :has() 接受一个 <relative-selector-list>,其参数本质上复杂选择器(因为它们(可能隐式地)以组合符开头)。这意味着 :has() 不能用于不允许复杂选择器的上下文中;其参数将被保证为无效。

例如,以下选择器仅匹配包含 <img> 子元素的 <a> 元素
a:has(> img)

以下选择器匹配紧随另一个 <dt> 元素之后的 <dt> 元素

dt:has(+ dt)

以下选择器匹配不包含任何标题元素的 <section> 元素

section:not(:has(h1, h2, h3, h4, h5, h6))

请注意,在上述选择器中,顺序很重要。交换两个伪类的嵌套,如

section:has(:not(h1, h2, h3, h4, h5, h6))

...将导致匹配任何包含非标题元素的 <section> 元素。

5. 元素选择器

5.1. 类型(标签名)选择器

类型选择器是文档语言元素类型的名称,代表文档树中该元素类型的实例。

例如,选择器 h1 代表文档中的一个 h1 元素。

类型选择器写作 CSS 限定名:一个带有可选命名空间前缀的标识符[CSS3NAMESPACE](参见 § 5.3 元素选择器中的命名空间。)

5.2. 通用选择器

测试

通用选择器是一种特殊的类型选择器,代表任何元素类型的元素。

它写作一个以星号(* U+002A)作为本地名称的 CSS 限定名。像类型选择器一样,通用选择器可以由命名空间限定,将其限制为仅属于该命名空间的元素,并且受§ 5.3 元素选择器中的命名空间中定义的默认命名空间影响。

除非元素是无特征的,否则通用选择器的存在对元素是否匹配该选择器没有影响。(无特征元素不匹配任何选择器,包括通用选择器。)

通用选择器遵循与其他类型选择器相同的语法规则:每个复合选择器中只能出现一个,并且它必须是复合选择器中的第一个简单选择器

注意:在某些情况下,添加通用选择器可以使选择器更易于阅读,即使它对匹配行为没有影响。例如,div :first-childdiv:first-child 在一眼看上去时很难区分,但将前者写为 div *:first-child 则使区别显而易见。

5.3. 元素选择器中的命名空间

类型选择器通用选择器允许有一个可选的命名空间组件:一个预先声明的命名空间前缀可以加在元素名称之前,并用命名空间分隔符“竖线”(| U+007C)隔开。(关于 XML 中命名空间的使用,参见例如 [XML-NAMES]。)它在每种形式中具有以下含义

ns|E
命名空间 ns 中名称为 E 的元素
*|E
任何命名空间中名称为 E 的元素,包括没有命名空间的元素
|E
没有命名空间且名称为 E 的元素
E
如果选择器没有声明默认命名空间,则这等同于 *|E。否则,它等同于 ns|E,其中 ns 为默认命名空间。
CSS 示例
@namespace foo url(http://www.example.com);
foo|h1 { color: blue }  /* first rule */
foo|* { color: yellow } /* second rule */
|h1 { color: red }      /* ...*/
*|h1 { color: green }
h1 { color: green }

第一个规则(不计算 @namespace at-rule)将仅匹配 "http://www.example.com" 命名空间中的 h1 元素。

第二个规则将匹配 "http://www.example.com" 命名空间中的所有元素。

第三个规则将仅匹配没有命名空间的 h1 元素。

第四条规则将匹配任何命名空间中的 h1 元素(包括那些没有命名空间的元素)。

最后一条规则与第四条规则等效,因为没有定义默认命名空间。

如果声明了 默认命名空间,那么其中不包含 类型选择器复合选择器 仍然只匹配该默认命名空间中的元素。

例如,在下面的样式表中
@namespace url("http://example.com/foo");

.special { ... }

.special 选择器仅匹配 "http://example.com/foo" 命名空间中的元素,即使并未出现对该类型名称(在 DOM 中与命名空间配对)的引用。

包含未预先 声明 的命名空间前缀的 类型选择器通用选择器无效选择器

5.4. 已定义伪类::defined

测试

在某些宿主语言中,元素可能存在“已定义”/“已构造”与否的区别。:defined 伪类 匹配宿主语言所规定的完全定义的元素。

如果宿主语言没有这种区别,则其中的所有元素都匹配 :defined

在 HTML 中,所有内置元素都被视为已定义,因此以下示例将始终匹配
p:defined { ... }

自定义元素 则相反,它们最初是未定义的,只有在 正确注册 后才会变得已定义。这意味着 :defined 伪类可用于隐藏自定义元素,直到它被注册为止。

custom-element { visibility: hidden }
custom-element:defined { visibility: visible }

6. 属性选择器

测试

选择器允许表示元素的属性。当选择器被用作与元素匹配的表达式时,如果元素具有匹配该属性选择器所表示属性的属性,则认为该 属性选择器 匹配该元素。

添加用于 多值匹配 的逗号分隔语法?例如 [rel ~= next, prev, up, first, last]

6.1. 属性存在和值选择器

CSS2 引入了四个属性选择器

[att]
表示具有 att 属性的元素,无论该属性的值为何。
[att=val]
表示具有 att 属性且值恰好为 "val" 的元素。
[att~=val]
表示具有 att 属性且值是由 空格 分隔的词列表,其中一个是 "val" 的元素。如果 "val" 包含空格,它将永远无法匹配(因为词是由空格分隔的)。此外,如果 "val" 是空字符串,它也将永远无法匹配。
[att|=val]
表示具有 att 属性的元素,其值要么恰好为 "val",要么以 "val" 开头并紧随 "-" (U+002D)。这主要用于允许语言子代码匹配(例如,HTML 中 a 元素上的 hreflang 属性),如 BCP 47 ([BCP47]) 或其后续版本所述。关于 lang(或 xml:lang)语言子代码匹配,请参阅 :lang() 伪类。

属性值必须是 <ident-token><string-token>[CSS3SYN]

示例

以下属性选择器表示携带 title 属性的 h1 元素,无论其值为何

h1[title]

在以下示例中,选择器表示 class 属性值恰好为 "example" 的 span 元素

span[class="example"]

多个属性选择器可以用于表示元素的多个属性,或同一属性的多个条件。在这里,选择器表示一个 span 元素,其 hello 属性的值恰好为 "Cleveland",且其 goodbye 属性的值恰好为 "Columbus"

span[hello="Cleveland"][goodbye="Columbus"]

以下 CSS 规则说明了 "=" 和 "~=" 之间的区别。第一个选择器会匹配,例如,rel 属性值为 "copyright copyleft copyeditor" 的 a 元素。第二个选择器仅匹配 href 属性值恰好为 "https://w3org.cn/" 的 a 元素。

a[rel~="copyright"] { ... }
a[href="https://w3org.cn/"] { ... }

以下选择器表示 hreflang 属性恰好为 "fr" 的 a 元素。

a[hreflang=fr] 

以下选择器表示 hreflang 属性值以 "en" 开头的 a 元素,包括 "en"、"en-US" 和 "en-scouse"

a[hreflang|="en"] 

以下选择器表示任何 character 属性具有两个不同值之一的 DIALOGUE 元素

DIALOGUE[character=romeo]
DIALOGUE[character=juliet]

6.2. 子字符串匹配属性选择器

提供了三个额外的属性选择器,用于匹配属性值中的子字符串

[att^=val]
表示具有 att 属性且值以 "val" 为前缀的元素。如果 "val" 是空字符串,则该选择器不匹配任何内容。
[att$=val]
表示具有 att 属性且值以 "val" 为后缀的元素。如果 "val" 是空字符串,则该选择器不匹配任何内容。
[att*=val]
表示具有 att 属性且值包含至少一个 "val" 子字符串的元素。如果 "val" 是空字符串,则该选择器不匹配任何内容。

属性值必须是 <ident-token><string-token>

示例:以下选择器表示引用图像的 HTML object 元素
object[type^="image/"] 

以下选择器表示具有 href 属性且值以 ".html" 结尾的 HTML a 元素。

a[href$=".html"] 

以下选择器表示具有 title 属性且值包含子字符串 "hello" 的 HTML 段落

p[title*="hello"] 

6.3. 大小写敏感性

测试

默认情况下,选择器中属性名称和值的大小写敏感性取决于文档语言。

为了不顾文档语言规则,以 ASCII 大小写不敏感 的方式匹配属性值,属性选择器可以在右方括号 (]) 前包含标识符 i。当存在此标志时,UA 必须以 ASCII 大小写不敏感 的方式匹配属性值(即 [a-z] 和 [A-Z] 被视为等效)。

或者,属性选择器可以在右方括号 (]) 前包含标识符 s;在这种情况下,UA 必须以大小写敏感的方式匹配值,采用“等同于”的语义 [INFRA],无论文档语言规则如何。

与选择器语法的其余部分一样,is 标识符本身是 ASCII 大小写不敏感的

以下规则将设置 frame 属性值为 hsides 的样式,无论是表示为 hsidesHSIDEShSides 等,即使在属性值大小写敏感的 XML 环境中也是如此。
[frame=hsides i] { border-style: solid none; } 
以下规则将使 type="a" 属性的列表样式与 type="A" 不同,尽管 HTML 将 type 属性定义为大小写不敏感。
[type="a" s] { list-style: lower-alpha; }
[type="A" s] { list-style: upper-alpha; }

注意: 一些文档模型在解析时会规范化不区分大小写的属性值,导致无法检查字符串是否为大小写敏感匹配。通过 s 标志进行的大小写敏感匹配仅在保留原始大小写的系统中才可行。

6.4. 属性选择器与命名空间

测试

属性选择器中的属性名被作为 CSS 限定名 给出:可以在属性名称前加上预先 声明 过的命名空间前缀,并以命名空间分隔符“竖线”(|) 分隔。遵循 XML 命名空间建议,默认命名空间不适用于属性,因此不带命名空间组件的属性选择器仅适用于没有命名空间的属性(等同于 |attr)。星号可用于命名空间前缀,表示该选择器将匹配所有属性名,而无需考虑属性的命名空间。

包含未预先 声明 的命名空间前缀的属性名称的属性选择器是无效的选择器。

CSS 示例
@namespace foo "http://www.example.com";
[foo|att=val] { color: blue }
[*|att] { color: yellow }
[|att] { color: green }
[att] { color: green }

第一条规则仅匹配 "http://www.example.com" 命名空间中属性 att 值为 "val" 的元素。

第二条规则仅匹配具有属性 att 的元素,而不论该属性的命名空间如何(包括无命名空间)。

最后两条规则等效,将仅匹配属性 att 不在命名空间中的元素。

6.5. DTD 中的默认属性值

属性选择器表示文档树中的属性值。该文档树是如何构建的超出了选择器的范围。在某些文档格式中,默认属性值可以在 DTD 或其他地方定义,但它们只有在出现在文档树中时才能被属性选择器选中。选择器的设计应使其无论默认值是否包含在文档树中都能正常工作。

例如,XML UA 可以(但不被要求)读取 DTD 的“外部子集”,但被要求在文档的“内部子集”中查找默认属性值。(关于这些子集的定义,请参见例如 [XML10]。)根据 UA 的不同,DTD 外部子集中定义的默认属性值可能会或可能不会出现在文档树中。

识别 XML 命名空间的 UA 可以(但不被要求)利用其对该命名空间的知识,将默认属性值视为如同它们出现在文档中一样。(例如,XHTML UA 不被要求使用其对 XHTML DTD 的内置知识。关于 XML 1.0 中命名空间的详细信息,请参阅例如 [XML-NAMES]。)

注意: 通常,实现选择忽略外部子集。这对应于 XML 规范定义的非验证处理器的行为。

示例

考虑一个具有属性 radix 的元素 EXAMPLE,其默认值为 "decimal"。DTD 片段可能是

<!ATTLIST EXAMPLE radix (decimal,octal) "decimal"> 

如果样式表包含规则

EXAMPLE[radix=decimal] { /*... default property settings ...*/ }
EXAMPLE[radix=octal]   { /*... other settings...*/ }

第一条规则可能不会匹配那些通过默认方式(即未显式设置)设置 radix 属性的元素。为了捕获所有情况,必须去掉默认值的属性选择器

EXAMPLE                { /*... default property settings ...*/ }
EXAMPLE[radix=octal]   { /*... other settings...*/ }

在这里,因为选择器 EXAMPLE[radix=octal] 比仅类型选择器更具体,第二条规则中的样式声明将覆盖第一条规则中 radix 属性值为 "octal" 的元素的样式声明。需要特别注意确保所有仅适用于默认情况的属性声明在非默认情况的样式规则中被覆盖。

6.6. 类选择器

测试

类选择器 由句点(. U+002E)后紧跟标识符给出。它表示属于由该标识符定义的类(由文档语言定义)的元素。例如,在 [HTML5][SVG11][MATHML] 中,类的成员身份由 class 属性给出:在这些语言中,它等同于应用于局部 class 属性的 ~= 符号(即 [class~=identifier])。

CSS 示例

我们可以如下为所有 class~="pastoral" 的元素分配样式信息

*.pastoral { color: green }  /* all elements with class~=pastoral */ 

或者只写

.pastoral { color: green }  /* all elements with class~=pastoral */ 

以下仅为 class~="pastoral" 的 H1 元素分配样式

H1.pastoral { color: green }  /* H1 elements with class~=pastoral */ 

给定这些规则,下方的第一个 H1 实例不会有绿色文本,而第二个会有

<H1>Not green</H1>
<H1 class="pastoral">Very green</H1>

以下规则匹配任何 class 属性被分配了包含 pastoralmarine空格 分隔值列表的 P 元素

p.pastoral.marine { color: green } 

此规则在 class="pastoral blue aqua marine" 时匹配,但在 class="pastoral blue" 时不匹配。

注意: 由于 CSS 赋予了 "class" 属性相当大的威力,作者可能会构思基于几乎没有关联呈现的元素(如 HTML 中的 divspan)并通过 "class" 属性分配样式信息的“文档语言”。作者应避免这种做法,因为文档语言的结构元素通常具有公认和接受的含义,而作者定义的类可能没有。

注意: 如果元素具有多个类属性,则在搜索类之前,必须在这些值之间用空格连接它们的值。目前,工作组尚不知道有任何方式可以到达这种情况,因此在本规范中,此行为明确为非规范性的。

当匹配处于 怪异模式 (quirks mode) 的文档时,类名必须以 ASCII 大小写不敏感 的方式匹配;否则类选择器是大小写敏感的,仅匹配与之 完全相同 的类名。[INFRA]

6.7. ID 选择器

测试

文档语言可能包含声明为 ID 类型的属性。ID 类型属性的特别之处在于,在一个符合标准的文档中,无论承载它们的元素类型如何,没有两个此类属性可以具有相同的值;无论文档语言如何,ID 类型属性都可用于唯一标识其元素。在 HTML 中,所有 ID 属性都被命名为 id;XML 应用可能以不同的方式命名 ID 属性,但相同的限制仍然适用。元素上的哪个属性被视为“ID 属性”由文档语言定义。

ID 选择器 由“井号”(U+0023, #) 后紧跟 ID 值组成,该值必须是 CSS 标识符。ID 选择器表示具有与 ID 选择器中的标识符匹配的标识符的元素实例。(在不符合标准的文档中,可能存在多个元素匹配单个 ID 选择器的情况。)

示例:以下 ID 选择器表示 ID 类型属性值为 "chapter1" 的 h1 元素
h1#chapter1 

以下 ID 选择器表示 ID 类型属性值为 "chapter1" 的任何元素

#chapter1 

以下选择器表示 ID 类型属性值为 "z98y" 的任何元素。

*#z98y 

注意: 在 XML 1.0 [XML10] 中,关于哪个属性包含元素 ID 的信息包含在 DTD 或模式中。解析 XML 时,UA 并不总是读取 DTD,因此可能不知道元素的 ID 是什么(尽管 UA 可能拥有允许其确定该命名空间的 ID 属性的特定知识)。如果样式表作者知道或怀疑 UA 可能不知道元素的 ID 是什么,则应使用普通的属性选择器:例如 [name=p371] 而不是 #p371

如果元素具有多个 ID 属性,则出于 ID 选择器的目的,所有这些属性都必须被视为该元素的 ID。这种情况可以通过结合使用 xml:id、DOM3 Core、XML DTD 和特定于命名空间的知识来达到。

当匹配处于 怪异模式 (quirks mode) 的文档时,ID 必须以 ASCII 大小写不敏感 的方式匹配;否则 ID 选择器是大小写敏感的,仅匹配与之 完全相同 的 ID。[INFRA]

7. 语言伪类

7.1. 方向性伪类::dir()

测试

:dir() 伪类允许作者编写根据 文档语言 确定的方向性来表示元素的选择器。例如,[HTML5] 基于 dir 属性、周围文本和其他因素的组合,定义了 如何确定元素的方向性。作为另一个例子,国际化标签集 [ITS20]its:dirdirRule 元素能够定义 [XML10] 中元素的方向性。

:dir() 伪类不基于样式状态进行选择——例如,CSS direction 属性不会影响它是否匹配。

伪类 :dir(ltr) 表示方向性为从左到右 (ltr) 的元素。伪类 :dir(rtl) 表示方向性为从右到左 (rtl) 的元素。:dir() 的参数必须是单个标识符,否则选择器无效。标识符和括号之间可选择性地留有空格。非 ltrrtl 的值并非无效,但不匹配任何内容。(如果未来的标记规范定义了其他方向性,则选择器可能会被扩展以允许相应的值。)

:dir(C)[dir=C] 之间的区别在于,[dir=C] 仅针对元素上的给定属性执行比较,而 :dir(C) 伪类使用 UA 对文档语义的了解来执行比较。例如,在 HTML 中,元素的方向性会继承,因此没有 dir 属性的子元素将具有与其具有有效 dir 属性的最近祖先相同的方向性。作为另一个例子,在 HTML 中,匹配 [dir=auto] 的元素将根据其内容确定的已解析方向性,匹配 :dir(ltr):dir(rtl)[HTML5]

7.2. 语言伪类::lang()

测试

如果文档语言指定了如何确定元素的(人类) 内容语言,则可以编写基于其 内容语言 表示元素的选择器。:lang() 伪类接受一个或多个 语言范围 的逗号分隔列表,表示其 内容语言 是其参数中列出的语言之一的元素。:lang() 中的每个 语言范围 都必须是有效的 CSS <ident><string>。(因此,包含星号的语言范围等,必须被正确转义或引用为字符串,例如 :lang(\*-Latn):lang("*-Latn")。)

注意: 元素的 内容语言 由文档语言定义。

例如,在 HTML [HTML5] 中,内容语言lang 属性、meta 元素中的信息以及可能的协议(例如来自 HTTP 标头)组合决定。XML 语言可以使用 xml:lang 属性来指示元素的语言信息。[XML10]

如果元素的 内容语言(以 BCP 47 语法表示)在 [RFC4647] Matching of Language Tags(第 3.3.2 节)定义的 扩展过滤 操作中与给定的 语言范围 匹配,则其 内容语言 匹配该 语言范围。在 扩展过滤 操作之前,内容语言语言范围 都必须根据 [RFC5646] 第 4.5 节进行 规范化 并转换为 extlang 形式。匹配是在 ASCII 范围内以大小写不敏感的方式进行的。

语言范围 无需是有效的语言代码即可执行此比较。

为此,通配符 语言范围 ("*") 不匹配语言未标记(例如 lang="")的元素,但匹配语言被标记为未定(lang=und)的元素。由空字符串组成的 语言范围 (:lang("")) (仅)匹配语言未标记的元素。

注意: 建议文档和协议使用来自 [BCP47] 或其后续版本的代码来指示语言,对于基于 XML 的格式,通过 xml:lang 属性来指示。[XML10] 参见 “FAQ: Two-letter or three-letter language codes.”

示例:以下两个选择器表示处于比利时法语或德语中的 HTML 文档。接下来的两个选择器表示处于比利时法语或德语中任意元素内的 q 引语。
html:lang(fr-be)
html:lang(de)
:lang(fr-be) > q
:lang(de) > q

注意: :lang(C)|= 运算符之间的一个区别是,|= 运算符仅针对元素上的给定属性执行比较,而 :lang(C) 伪类使用 UA 对文档语义的了解来执行比较。

在此 HTML 示例中,只有 BODY 匹配 [lang|=fr](因为它具有 LANG 属性),但 BODY 和 P 都匹配 :lang(fr)(因为两者都使用法语)。P 不匹配 [lang|=fr],因为它没有 LANG 属性。
<body lang=fr>
  <p>Je suis français.</p>
</body>
:lang(C)|= 运算符之间的另一个区别是 :lang(C) 执行隐式通配符匹配。

例如,:lang(de-DE) 将匹配 de-DEde-DE-1996de-Latn-DEde-Latf-DEde-Latn-DE-1996 中的所有内容,而其中 [lang|=de-DE] 将仅匹配 de-DEde-DE-1996

要在第一个子标签(主语言)上执行通配符匹配,必须使用星号:*-CH 将匹配 de-CHit-CHfr-CHrm-CH 中的所有内容。

要使用此类语言范围匹配来针对元素的 lang 属性值进行选择,请将属性选择器和语言伪类一起使用,例如 [lang]:lang(de-DE)

注意: 通配符语言匹配和逗号分隔列表是 Level 4 中的新功能。

8. 位置伪类

测试

The :any-link 伪类表示充当超链接源锚点的元素。例如,在 [HTML5] 中,任何带有 href 属性的 aarea 元素都是超链接,因此匹配 :any-link。如果元素匹配 :link:visited 中的任何一个,它就匹配该元素,且等同于 :is(:link, :visited)

测试

用户代理通常会将未访问的超链接与已访问的超链接显示为不同样式。Selectors 提供了伪类 :link:visited 来进行区分。

这两种状态是互斥的。

一段时间后,用户代理可以选择将已访问的链接恢复为(未访问的):link 状态。

:visited 伪类具有明显的隐私影响——让随机网站知道您访问过其他什么网站可能会导致许多问题——因此用户代理必须在其 :visited 实现中保护用户隐私。

本规范有意不明确规定如何在此方面保护用户隐私,以便为用户代理在这一领域进行创新留出空间。不过,以下是建议的方法:
例如,选择器 .footnote:visited 允许在脚注链接被访问过的情况下以不同方式对其进行样式设置,从而让页面用户知道他们可能不需要再次点击该脚注。

8.3. 目标伪类::target

在某些文档语言中,文档的 URL 可以通过 URL 的片段(fragment)进一步指向文档的特定元素。以这种方式指向的元素是文档的目标元素。

在 HTML 中,片段指向页面中具有相同 ID 的元素。例如,URL https://example.com/index.html#section2 指向文档 https://example.com/index.htmlid="section2" 的元素。

:target 伪类匹配文档的目标元素。如果文档的 URL 没有片段标识符,则文档没有目标元素。

示例
p.note:target 

此选择器表示一个类名为 notep 元素,它是所引 URL 的目标元素。

CSS 示例:在这里,:target 伪类用于使目标元素变为红色,并在其前放置一张图片(如果存在的话)。
:target { color : red }
:target::before { content : url(target.png) }

注意:本规范之前定义了一个 :target-within 伪类,类似于 :focus-within。它已被移除,取而代之的是 :has(:target),希望这足以解决相同的用例。

8.4. 参考元素伪类::scope

测试

在某些上下文中,选择器是相对于一个或多个作用域根(scoping roots)进行匹配的,例如在 [DOM] 中调用 querySelector() 方法时。:scope 伪类表示此作用域根,它可以是真实的元素,也可以是虚拟的(例如 DocumentFragment)。

如果没有作用域根,则 :scope 表示元素所在树的根(相当于影子树中的 :host,否则相当于 :root)。旨在让此伪类匹配特定元素而非此树根元素的规范,必须定义其作用域根

虚拟作用域根是表示文档片段根的某个对象,可以在选择器模式中使用,以表示其他元素与此作用域根的关系,充当其所表示文档片段中任何根元素的父元素。虚拟作用域根无特性(featureless)的,且不能作为选择器主体

例如,如果您有一个 DocumentFragment df,那么 df.querySelectorAll(":scope > .foo") 将匹配文档片段中所有“顶层”的 .foo 元素(即那些以文档片段为其 parentNode 的元素)。

但是,df.querySelector(":scope") 将不会匹配任何内容,因为文档片段本身不能作为选择器主体

9. 用户动作伪类

交互式用户界面有时会根据用户操作改变渲染效果。Selectors 为选择用户正在操作的元素提供了多个用户动作伪类。(在非交互式用户代理中,这些伪类是合法的,但不匹配任何元素。)

用户动作伪类不是互斥的。一个元素可以同时匹配多个此类伪类。

示例
a:hover   /* user hovers over the link */
a:focus   /* user focuses the link     */

a:focus:hover
/* user hovers over the link while it’s focused */

某些用户动作伪类除了在具有相关属性的特定元素上匹配外,还会在其祖先元素上匹配::hover:active:focus-within。具体来说,如果它们在给定元素上匹配,它们也会在元素扁平树的祖先上匹配,直到并包含第一个顶层元素或元素(以先遇到的为准)。

注意:命中测试(hit-testing)的具体细节对于了解本节定义的多个伪类何时适用是必要的,目前尚未定义,但将在未来定义。

9.1. 指针悬停伪类::hover

测试

:hover 伪类适用于用户使用指向设备指定元素(或伪元素)时,但不一定激活它。例如,可视用户代理可以在光标(鼠标指针)悬停在由元素生成的框上时应用此伪类。由于硬件限制(例如无法检测悬停的触控笔设备)而无法检测悬停的交互式用户代理仍然是合规的;在该 UA 中,此选择器将根本不会匹配。

如果元素在扁平树中的后代(包括非元素节点,如文本节点)满足上述条件,则该元素也会匹配 :hover

文档语言可以定义元素匹配 :hover 的其他方式。例如,[HTML5] 定义了当其 label 被悬停时,关联的控件元素匹配 :hover

注意:由于 :hover 状态可以因为其子元素被指向设备指定而应用于元素,因此 :hover 有可能应用于并未位于指向设备下方的元素。

9.2. 激活伪类::active

:active 伪类在元素正被用户“激活”时适用,具体定义由宿主语言决定;例如,在超链接被触发时。

此外,:active 伪类在任何元素(或伪元素)的生成框正被指向设备主动指示(处于“按下”状态)时适用,例如在用户按下主鼠标按钮并释放之间,或者手指正在触摸屏上按压时。

注意:[HTML5] 定义了 HTML 元素被激活的具体条件

如果元素在扁平树中的后代(包括非元素节点,如文本节点)满足上述条件,该元素也会匹配 :active

9.3. 输入焦点伪类::focus

测试

:focus 伪类在元素(或伪元素)拥有焦点(接受键盘或其他形式的输入)时适用。

对于哪些元素可以获得 :focus,可能存在文档语言或实现特定的限制。例如,[HTML] 定义了一个可获得焦点的区域列表。

文档语言可以定义元素匹配 :focus 的其他方式,但 :focus 伪类绝不能自动传播到父元素——如果希望匹配父元素,请参见 :focus-within。(如果 :focus 由于其他机制被设定为传播,则它可能仍然应用于父元素,但不能仅因为是父元素就应用于父元素。)

作者希望能将 :focus 从表单控件传播到其关联的 label 元素;主要反对意见似乎是实现难度。请参阅 CSSWG 问题 (CSS)WHATWG 问题 (HTML)

9.4. 焦点指示伪类::focus-visible

测试

虽然 :focus 伪类总是匹配当前获得焦点的元素,但用户代理只有在某些情况下才可见地指示焦点(例如通过绘制“焦点环”),而是使用多种启发式方法仅在对用户最有帮助时才可见地指示焦点。:focus-visible 伪类仅在这些情况下匹配获得焦点的元素(或伪元素),允许作者更改焦点指示器的外观,而不改变焦点指示器出现的时机

在此示例中,所有可获得焦点的元素在 :focus-visible 时获得明显的黄色轮廓,链接在 :focus-visible 时既获得黄色轮廓又获得黄色背景。这些样式在整个页面中保持一致,并且由于其粗体样式而易于辨识,但仅在用户可能需要了解页面焦点位置时才会出现。
:root {
  --focus-gold: #ffbf47;
}

:focus-visible  {
  outline: 3px solid var(--focus-gold);
}

a:focus-visible {
  background-color: var(--focus-gold);
}
用户代理可以选择自己何时指示焦点的启发式方法;不过,以下(非规范性)建议可用作何时对当前获得焦点的元素指示焦点的起点:

用户代理也应使用 :focus-visible 来指定默认焦点样式,这样使用 :focus-visible 的作者将不需要同时禁用默认的 :focus 样式。

9.5. 焦点容器伪类::focus-within

测试

:focus-within 伪类适用于任何 :focus 伪类适用的元素(或伪元素),也适用于其扁平树中的后代(包括非元素节点,如文本节点)满足匹配 :focus 条件的元素(或伪元素)。

10. 资源状态伪类

本节中的伪类适用于表示已加载资源(特别是图像/视频)的元素,并允许作者根据其状态的某种质量来选择它们。

10.1. 媒体播放状态::playing:paused:seeking 伪类

测试

:playing 伪类表示能够“播放”或“暂停”且当前处于“播放”状态的元素。(这既包括元素显式播放时,也包括由于与用户意图无关的某种原因暂时停止但会在该原因解决后自动恢复时,例如“缓冲”或“停顿”状态。)

:paused 伪类表示能够“播放”或“暂停”且当前处于“暂停”状态(即“播放”)的元素。(这既包括显式的“暂停”状态,也包括其他非播放状态,例如“已加载,尚未激活”等。)

:seeking 伪类表示能够“搜寻(seeking)”且当前处于“搜寻”状态的元素。(对于 HTML 的 audiovideo 元素,请参见 HTML § 4.8.11.9 Seeking。)

10.2. 媒体加载状态::buffering:stalled 伪类

测试

:buffering 伪类表示能够“播放”或“暂停”且由于正在积极尝试获取媒体数据但尚未获得足够数据来恢复播放而无法继续播放的元素。(请注意,当元素处于“缓冲”状态时,仍被视为“播放”。每当 :buffering 匹配一个元素时,:playing 也会匹配该元素。)

:stalled 伪类表示由于正在积极尝试获取媒体数据但在一段时间内未能接收到任何数据而无法继续播放的元素。对于 HTML 的 audiovideo 元素,此时间段为媒体元素停顿超时(media element stall timeout)[HTML](请注意,与 :buffering 伪类一样,当元素处于“停顿”状态时,仍被视为“播放”。每当 :stalled 匹配一个元素时,:playing 也会匹配该元素。)

10.3. 声音状态::muted:volume-locked 伪类

测试

:muted 伪类表示能够发出声音但当前被“静音”(强制无声)的元素。(对于 HTML 的 audiovideo 元素,请参见 muted[HTML]

:volume-locked 伪类表示能够发出声音且当前音量被 UA 或用户“锁定”的元素,因此页面作者无法更改它。(对于 HTML 的 audiovideo 元素,请参见设置元素有效媒体音量(effective media volume)的算法。[HTML]

11. 元素显示状态伪类

11.1. 折叠状态::open 伪类

测试

:open 伪类表示同时具有“开启”和“关闭”状态且当前处于“开启”状态的元素。

“开启”和“关闭”的确切含义是特定于宿主语言的,但以 HTML 的 detailsselectdialoginput 元素为例,所有这些元素都可以切换为“开启”以显示更多内容(或者在 dialog 的情况下显示任何内容)。

注意:“开启”或“关闭”是一种语义状态。当前未显示的元素(例如具有 visibility: collapse,或属于 display: none 子树的元素)仍然可以是“开启”的,并将匹配 :open

注意:一旦已知支持 :open 的完整元素集,未来可能会添加一个 ":closed" 伪类。

11.2. 弹窗状态::popover-open 伪类

测试

:popover-open 伪类表示具有“弹窗显示中(popover-showing)”和“弹窗隐藏(popover-hidden)”两种状态,且当前处于“弹窗显示中”状态的元素。

注意:这与 :open 不同,因为一个元素可以具有元素特定的开启和关闭状态,同时也具有与作为弹窗相关联的单独的显示中和隐藏状态。

“弹窗显示中”和“弹窗隐藏”状态的确切含义是特定于宿主语言的,可以通过 HTML popover 属性及关联的弹窗可见性状态来例证。

测试

:modal 伪类表示处于一种状态的元素,在该状态下,在元素被取消前,除该元素之外的所有交互都被排除。多个元素可以同时是 :modal,但其中只有一个处于活动状态(能够接收输入)。

例如,dialog 元素在使用 showModal() API 打开时是 :modal 的。同样,:fullscreen 元素在使用 requestFullscreen() API 打开时也是 :modal 的,因为它阻止了与页面其余部分的交互。

11.4. 全屏演示状态::fullscreen 伪类

:fullscreen 伪类表示以占用屏幕大部分(通常是全部)空间模式显示的元素,例如由全屏 API 定义的模式。[FULLSCREEN]

11.5. 画中画演示状态::picture-in-picture 伪类

:picture-in-picture 伪类表示以占用视口大部分空间模式显示,且其视口在被显示于其他内容之上时被限制在屏幕一部分的元素,例如使用画中画 API 时。[picture-in-picture]

12. 输入伪类

本节中的伪类主要适用于接收用户输入的元素,例如 HTML 的 input 元素。

12.1. 输入控件状态

12.1.1. :enabled:disabled 伪类

测试

:enabled 伪类表示处于启用状态的用户界面元素;此类元素必须具有相应的禁用状态。

相反,:disabled 伪类表示处于禁用状态的用户界面元素;此类元素必须具有相应的启用状态。

什么构成启用状态、禁用状态和用户界面元素取决于宿主语言。在典型文档中,大多数元素既不匹配 :enabled 也不匹配 :disabled。例如,[HTML5] 定义非禁用的交互式元素:enabled,并且任何此类明确禁用的元素为 :disabled

注意:可能影响用户与特定用户界面元素交互能力的 CSS 属性不会影响它是否匹配 :enabled:disabled;例如,displayvisibility 属性对元素的启用/禁用状态没有影响。

12.1.2. 可变性伪类::read-only:read-write

测试

如果元素是用户可更改的(由文档语言定义),则匹配 :read-write。否则,它是 :read-only

例如,在 [HTML5] 中,非禁用且非只读的 <input> 元素:read-write,任何设置了 contenteditable 属性为真状态的元素也是如此。

12.1.3. 占位符显示伪类::placeholder-shown

测试

输入元素有时会显示占位符文本,作为对用户输入内容的提示。例如,请参见 [HTML5] 中的 placeholder 属性。:placeholder-shown 伪类匹配正在显示此类占位符文本的输入元素,无论该文本是由属性提供、由实际元素提供,还是由用户代理 (UA) 暗示的。

例如,根据 [HTML] 的语义,placeholder 属性在 inputtextarea 元素上提供了占位符文本。因此,只要显示此类占位符文本,:placeholder-shown 类就会应用。

12.1.4. 自动填充伪类::autofill

:autofill 伪类表示已被用户代理自动填充,且随后未被用户更改的输入元素。

12.1.5. 默认选项伪类::default

:default 伪类适用于一组相似元素中默认的一个或多个 UI 元素。通常适用于上下文菜单项、按钮和选择列表/菜单。

一个例子是一组按钮中的默认提交按钮。另一个例子是弹出菜单中的默认选项。在多选组(例如用于披萨配料)中,多个元素可以匹配 :default。例如,[HTML5] 定义了 :default 匹配 表单中的“默认按钮”、<select> 中初始选中的 <option> 以及其他一些元素。

12.2. 输入值状态

12.2.1. 选中选项伪类::checked:unchecked:indeterminate

单选按钮和复选框元素可以由用户切换,某些菜单项在用户选择时会被“选中”。此状态由 输入值伪类 反映。

当此类元素被切换为“开启”时,:checked 伪类就会应用。例如,[HTML5] 定义了 选中的复选框、单选按钮和选中的 <option> 元素 匹配 :checked。同样,当此类元素被切换为“关闭”时,:unchecked 伪类就会应用。

如果一个可能匹配 :checked:unchecked 的元素既不处于“开启”也不处于“关闭”状态,则 :indeterminate 伪类就会应用。:indeterminate 也匹配那些没有“选中”概念,但其“值”仍处于不确定状态的元素,例如进度百分比未知的进度条。

这三个伪类是互斥的;一个元素一次最多只能匹配其中一个。(如果“选中”的概念不适用于它们,则可能一个都不匹配。)如果在宿主语言中“不确定”概念与“选中/未选中”概念不是互斥的(例如,在 HTML 中,复选框的“不确定”状态是一个独立于其“选中”布尔值的布尔值),则在匹配这些伪类时,不确定状态优先于选中/未选中状态。

例如,在 HTML 中

虽然 输入值伪类 本质上是动态的,并且可以由用户操作改变,但由于它们也可以基于文档中语义属性的存在(例如 [HTML5] 中的 selectedchecked 属性),因此它们适用于所有媒体。

12.3. 输入值检查

12.3.1. 有效性伪类::valid:invalid

当元素的原始内容或值相对于文档语言定义的数据有效性语义(例如 [XFORMS11][HTML5])是有效或无效时,该元素分别为 :valid:invalid。缺乏数据有效性语义的元素既不匹配 :valid 也不匹配 :invalid

注意:没有约束条件的元素(因此始终为 :valid)与根本没有数据有效性语义的元素(因此既不 :valid 也不 :invalid)之间是有区别的。例如,在 HTML 中,<input type="text"> 元素可能没有约束条件,但 p 元素根本没有任何有效性语义,因此它永远不会匹配这些伪类中的任何一个。

12.3.2. 范围伪类::in-range:out-of-range

:in-range:out-of-range 伪类仅适用于具有范围限制的元素。当元素绑定的值相对于文档语言定义的范围限制处于范围内或范围外时,该元素分别为 :in-range:out-of-range。缺乏数据范围限制或不是表单控件的元素既不匹配 :in-range 也不匹配 :out-of-range。例如,一个值为 11 的滑块元素,如果呈现为仅表示 1-10 值的滑块控件,则为 :out-of-range。另一个例子是值位“E”的菜单元素,恰好显示在一个只有“A”、“B”和“C”选项的弹出菜单中。

12.3.3. 可选性伪类::required:optional

测试

如果一个表单元素在其所属的表单能有效提交之前,其值是必须的或可选的,则该表单元素分别为 :required:optional。非表单元素既不是必填的也不是可选的。

12.3.4. 用户交互伪类::user-valid:user-invalid

测试

:user-invalid:user-valid 伪类分别表示输入不正确或正确的元素,但仅用户与之进行了显著交互之后。其目的是帮助用户识别输入中的错误。

这些伪类必须在用户尝试提交表单后,且在用户再次与输入元素交互或重置表单之前,至少匹配它们各自的元素。它们也可能在其他时间匹配,具体取决于向用户高亮显示错误的方式。例如,:user-invalid 可以在用户更改值并将焦点移至另一个元素后开始匹配 :invalid 输入元素;或者仅在用户成功更正输入后停止匹配。

宿主语言可以定义更精确的匹配规则或遵循平台约定;否则,确切的行为由 UA 定义。无论如何,:user-invalid 伪类必须仅匹配 :invalid 元素;而 :user-valid 伪类必须仅匹配 :valid 元素。有关 HTML 元素的具体规则,请参阅 HTML 规范[HTML]

例如,以下文档片段中的 input 元素在页面加载时就会匹配 :invalid(因为 input 的初始值违反了其最大值约束),但直到用户与该输入字段进行显著交互或尝试提交其所属的表单之前,它不会匹配 :user-invalid
<form>
  <label>
    Volume:
    <input name='vol' type=number min=0 max=10 value=11>
  </label>
  ...
</form>

13. 树结构伪类

测试

Selectors 引入了 结构伪类 的概念,以允许基于位于文档树中但无法由其他简单选择器或组合器表示的额外信息进行选择。

独立文本和其他非元素节点在计算元素在其父元素子列表中的位置时不被计算。计算元素在其父元素子列表中的位置时,索引编号从 1 开始。

结构伪类仅适用于文档树中的元素;它们永远不应匹配 伪元素

13.1. :root 伪类

测试

:root 伪类表示文档的根元素。

例如,在 DOM 文档中,:root 伪类匹配 文档元素。在 HTML 中,这将是 html 元素(除非脚本已被用于修改文档)。

13.2. :empty 伪类

测试

:empty 伪类表示没有子元素的元素(可选择包含 文档空白字符)。就文档树而言,只有数据长度不为零的元素节点和内容节点(例如 [DOM] 文本节点和实体引用)才被视为影响空性;注释、处理指令和其他节点不得影响元素是否被视为空。

示例:p:empty 是以下 HTML 片段中 p 元素的有效表示
<p></p>
<p>
<p> </p>
<p> <!-- comment --></p>

div:empty 不是以下片段中 <div> 元素的有效表示

<div>text</div>
<div><p></p></div>
<div>&nbsp;</div>
<div><p>bla</p></div>
<div>this is not <p>:empty</p></div>

注意:在 Selectors 2 和 Level 3 中,:empty 不匹配仅包含空白的元素。这一点已被更改,以便鉴于空白在 HTML 中通常是可折叠的,因此用于源代码格式化,特别是考虑到省略结束标签的元素很可能将此类空白吸收到其 DOM 文本内容中,作者认为为空的元素可以被该选择器选中,正如他们预期的那样。

13.3. 子索引伪类

测试

本节定义的伪类基于元素在 包含兄弟节点 中的索引来选择元素。

注意:Selectors 3 将这些选择器描述为基于元素在其父元素子列表中的索引来选择元素。(此描述保留在本节的名称以及多个伪类的名称中。)由于没有理由将其排除在匹配没有父元素或具有非元素父元素的元素之外,因此它们已被重新表述为引用元素在其兄弟节点中的相对索引。

13.3.1. :nth-child() 伪类

测试

:nth-child(An+B [of S]? ) 伪类标记法表示在由其 包含兄弟节点 组成的列表中,属于匹配 选择器列表 S 的第 An+B 个元素的元素,其中 S 是一个 <complex-real-selector-list>。如果省略 S,则默认为 *|*

An+B 标记法及其解释定义在 CSS Syntax 3 § 6 An+B 微语法 中;它代表对于任何非负整数 n 的任何索引 i = An + B

注意:对于这些目的,元素列表是 1-索引的;也就是说,元素的第一个子元素具有索引 1,并将由 :nth-child(2n+1) 匹配,因为当 n=0 时,表达式的计算结果为 1

例如,此选择器可以定位表格中的每隔一行,并可用于以四为周期交替段落文本的颜色。

示例
:nth-child(even)   /* represents the 2nd, 4th, 6th, etc elements
:nth-child(10n-1)  /* represents the 9th, 19th, 29th, etc elements */
:nth-child(10n+9)  /* Same */
:nth-child(10n+-1) /* Syntactically invalid, and would be ignored */

注意::nth-child() 伪类的特异性是单个伪类的特异性加上(如果指定了 SS 中最具体 复杂选择器 的特异性。请参阅 § 15 计算选择器的特异性。因此 S:nth-child(An+B):nth-child(An+B of S) 具有完全相同的特异性,尽管它们的行为确实不同(参见下面的示例)。

通过传递选择器参数,我们可以选择匹配该选择器的第 N 个元素。例如,以下选择器匹配前三个“重要”列表项,由 .important 类表示
:nth-child(-n+3 of li.important)

请注意,这与将选择器移到函数外部不同,例如

li.important:nth-child(-n+3)

此选择器只是选择前三个子元素(如果它们恰好也是“重要”列表项的话)。

这是使用选择器参数的另一个示例,以确保表格的斑马纹效果正常工作。

通常,为了对表格行进行斑马纹处理,作者会使用类似于以下的 CSS

tr {
  background: white;
}
tr:nth-child(even) {
  background: silver;
}

但是,如果某些行被隐藏且未显示,这可能会破坏模式,导致多个相邻行具有相同的背景颜色。假设行在 HTML 中使用 [hidden] 属性隐藏,以下 CSS 将稳健地对表格行进行斑马纹处理,保持适当的交替背景,无论哪些行被隐藏

tr {
  background: white;
}
tr:nth-child(even of :not([hidden])) {
  background: silver;
}

13.3.2. :nth-last-child() 伪类

:nth-last-child(An+B [of S]? ) 伪类标记法表示在由其 包含兄弟节点 组成的列表中,属于匹配 选择器列表 S 的第 An+B 个元素的元素,从末尾开始倒数。S<complex-real-selector-list>。如果省略 S,则默认为 *|*

注意::nth-last-child() 伪类的特异性,像 :nth-child() 伪类一样,结合了常规伪类的特异性与其选择器参数 S 的特异性。请参阅 § 15 计算选择器的特异性

CSS 语法模块 [CSS3SYN] 定义了 An+B 标记法

示例
tr:nth-last-child(-n+2)    /* represents the two last rows of an HTML table */

foo:nth-last-child(odd)    /* represents all odd foo elements in their parent element,
                              counting from the last one */

13.3.3. :first-child 伪类

测试

:first-child 伪类表示其 包含兄弟节点 中的第一个元素。与 :nth-child(1) 相同。

示例:以下选择器表示 p 元素,它是 div 元素的第一个子元素
div > p:first-child

此选择器可以表示以下片段中 div 内部的 p

<p> The last P before the note.</p>
<div class="note">
   <p> The first P inside the note.</p>
</div>

但不能表示以下片段中的第二个 p

<p> The last P before the note.</p>
<div class="note">
   <h2> Note </h2>
   <p> The first P inside the note.</p>
</div>

以下两个选择器通常是等效的

* > a:first-child /* a is first child of any element */
a:first-child /* Same (assuming a is not the root element) */

13.3.4. :last-child 伪类

测试

:last-child 伪类表示其 包含兄弟节点 中的最后一个元素。与 :nth-last-child(1) 相同。

示例:以下选择器表示列表项 li,它是排序列表 ol 的最后一个子元素。
ol > li:last-child

13.3.5. :only-child 伪类

测试

:only-child 伪类表示没有兄弟节点的元素。与 :first-child:last-child:nth-child(1):nth-last-child(1) 相同,但特异性较低。

13.4. 类型化子索引伪类

测试

本节中的伪类类似于 子索引伪类,但它们基于元素在其兄弟列表中 相同类型(标签名称)的元素中 的索引进行解析。

13.4.1. :nth-of-type() 伪类

:nth-of-type(An+B) 伪类标记法表示与 :nth-child(|An+B| of S) 将匹配的相同元素,其中 S 是与所讨论元素匹配的 类型选择器 和命名空间前缀。例如,当考虑 HTML img 元素是否匹配此 伪类 时,所讨论的 Shtml|img(假设已声明适当的 html 命名空间)。

CSS 示例:这允许作者交替浮动图像的位置
img:nth-of-type(2n+1) { float: right; }
img:nth-of-type(2n) { float: left; }

注意:如果元素的类型预先已知,则此伪类等同于使用带有类型选择器的 :nth-child()。也就是说,img:nth-of-type(2) 等同于 *:nth-child(2 of img)

13.4.2. :nth-last-of-type() 伪类

测试

:nth-last-of-type(An+B) 伪类标记法表示与 :nth-last-child(|An+B| of S) 将匹配的相同元素,其中 S 是与所讨论元素匹配的 类型选择器 和命名空间前缀。例如,当考虑 HTML img 元素是否匹配此 伪类 时,所讨论的 Shtml|img(假设已声明适当的 html 命名空间)。

示例:要表示 XHTML body 的所有 h2 子元素(第一个和最后一个除外),可以使用以下选择器
body > h2:nth-of-type(n+2):nth-last-of-type(n+2) 

在这种情况下,也可以使用 :not(),尽管选择器最终同样长

body > h2:not(:first-of-type):not(:last-of-type) 

13.4.3. :first-of-type 伪类

测试

:first-of-type 伪类所代表的元素与 :nth-of-type(1) 相同。

示例:以下选择器代表定义列表 dl 中的定义标题 dt,该 dt 是其父元素子列表中同类型元素的第一个。
dl dt:first-of-type

对于以下示例中的前两个 dt 元素,这是一个有效的描述,但对于第三个则不是。

<dl>
  <dt>gigogne</dt>
  <dd>
    <dl>
      <dt>fusée</dt>
      <dd>multistage rocket</dd>
      <dt>table</dt>
      <dd>nest of tables</dd>
    </dl>
  </dd>
</dl>

13.4.4. :last-of-type 伪类

测试

:last-of-type 伪类所代表的元素与 :nth-last-of-type(1) 相同。

示例:以下选择器代表表格行 tr 的最后一个数据单元格 td
tr > td:last-of-type

13.4.5. :only-of-type 伪类

测试

:only-of-type 伪类所代表的元素与 :first-of-type:last-of-type 相同。

14. 组合符 (Combinators)

14.1. 后代组合符 ( )

测试

有时,作者可能希望选择器描述文档树中另一个元素的后代元素(例如,“包含在 em 元素内的 H1 元素”)。后代组合符 表达了这种关系。

后代组合符是分隔两个复合选择器的空白字符。

A B 形式的选择器代表作为某个祖先元素 A 的任意后代的元素 B

示例:例如,考虑以下选择器
h1 em

它代表作为 em 元素的后代的 h1 元素。对于以下片段,这是一个正确且有效(但部分)的描述

<h1>This <span class="myclass">headline
is <em>very</em> important</span></h1>

以下选择器

div * p

代表一个作为 div 元素的孙元素或更深层后代的 p 元素。注意,"*" 两侧的空白不是通用选择器的一部分;该空白是一个组合符,表示 div 必须是某个元素的祖先,且该元素必须是 p 的祖先。以下结合了后代组合符和属性选择器的选择器,代表一个元素,该元素 (1) 设置了 href 属性,且 (2) 位于一个 p 内部,而该 p 本身又位于一个 div 内部

div p *[href]

14.2. 子代组合符 (>)

测试

子代组合符 描述了两个元素之间的父子关系。子代组合符由“大于号”(U+003E,>)码点构成,并分隔两个复合选择器

示例:以下选择器代表一个作为 body 子代的 p 元素
body > p

以下示例结合了后代组合符和子代组合符。

div ol>li p

它代表一个作为 li 元素后代的 p 元素;该 li 元素必须是 ol 元素的子代;该 ol 元素必须是 div 的后代。请注意,“>”组合符周围的可选空白已被省略。

有关选择元素第一个子项的信息,请参阅上文关于 :first-child 伪类的章节。

14.3. 相邻兄弟组合符 (+)

测试

相邻兄弟组合符 由“加号”(U+002B,+)码点构成,并分隔两个复合选择器。两个复合选择器所代表的元素在文档树中拥有相同的父元素,且第一个复合选择器所代表的元素紧邻在第二个复合选择器所代表的元素之前。在考虑元素的邻接性时,非元素节点(例如元素间的文本)会被忽略。

示例:以下选择器代表一个紧随 math 元素之后的 p 元素
math + p

以下选择器在概念上与前一个示例类似,不同之处在于它添加了一个属性选择器——它对 h1 元素施加了一个约束,即它必须具有 class="opener"

h1.opener + h2

14.4. 随后兄弟组合符 (~)

随后兄弟组合符 由“波浪号”(U+007E,~)码点构成,并分隔两个复合选择器。两个复合选择器所代表的元素在文档树中拥有相同的父元素,且第一个复合选择器所代表的元素位于第二个复合选择器所代表的元素之前(不必紧邻)。

h1 ~ pre

代表一个跟随 h1 之后的 pre 元素。对于以下内容,这是一个正确且有效(但部分)的描述

<h1>Definition of the function a</h1>
<p>Function a(x) has to be applied to all figures in the table.</p>
<pre>function a(x) = 12x/13.5</pre>

15. 计算选择器的特殊性 (Specificity)

选择器的 特殊性 计算方式如下

如果选择器是一个选择器列表,则该数值需针对列表中的每个选择器分别计算。针对该列表进行给定的匹配过程时,生效的特殊性是列表中匹配成功的选择器中最高的那一个。

少数伪类为其他选择器提供了“评估上下文”,因此它们的特殊性有特殊的定义

例如

特殊性的比较方式是按顺序比较三个组件:具有更大 A 值的特殊性更具特殊性;如果两个 A 值相等,则具有更大 B 值的特殊性更具特殊性;如果两个 B 值也相等,则具有更大 C 值的特殊性更具特殊性;如果所有值都相等,则两个特殊性相等。

由于存储限制,实现可能会限制 ABC 的大小。如果是这样,高于限制的值必须被截断到该限制,而不是溢出。

示例
*               /* a=0 b=0 c=0 */
LI              /* a=0 b=0 c=1 */
UL LI           /* a=0 b=0 c=2 */
UL OL+LI        /* a=0 b=0 c=3 */
H1 + *[REL=up]  /* a=0 b=1 c=1 */
UL OL LI.red    /* a=0 b=1 c=3 */
LI.red.level    /* a=0 b=2 c=1 */
#x34y           /* a=1 b=0 c=0 */
#s12:not(FOO)   /* a=1 b=0 c=1 */
.foo :is(.bar, #baz)
                /* a=1 b=1 c=0 */

注意:允许重复出现相同的简单选择器,且它们会增加特殊性。

注意:HTML style 属性中指定的样式的特殊性在 CSS 样式属性中已有描述[CSSSTYLEATTR]

16. 语法

测试

选择器根据以下语法进行解析

<selector-list> = <complex-selector-list>

<complex-selector-list> = <complex-selector>#
<complex-real-selector-list> = <complex-real-selector>#

<compound-selector-list> = <compound-selector>#

<simple-selector-list> = <simple-selector>#

<relative-selector-list> = <relative-selector>#
<relative-real-selector-list> = <relative-real-selector>#


<complex-selector> = <complex-selector-unit> [ <combinator>? <complex-selector-unit> ]*
<complex-selector-unit> = [ <compound-selector>? <pseudo-compound-selector>* ]!
<complex-real-selector> = <compound-selector> [ <combinator>? <compound-selector> ]*

<relative-selector> = <combinator>? <complex-selector>
<relative-real-selector> = <combinator>? <complex-real-selector>

<compound-selector> = [ <type-selector>? <subclass-selector>* ]!
<pseudo-compound-selector> =  <pseudo-element-selector> <pseudo-class-selector>*

<simple-selector> = <type-selector> | <subclass-selector>


<combinator> = '>' | '+' | '~' | [ '|' '|' ]

<wq-name> = <ns-prefix>? <ident-token>
<ns-prefix> = [ <ident-token> | '*' ]? '|'

<type-selector> = <wq-name> | <ns-prefix>? '*'

<subclass-selector> = <id-selector> | <class-selector> |
                      <attribute-selector> | <pseudo-class-selector>

<id-selector> = <hash-token>

<class-selector> = '.' <ident-token>

<attribute-selector> = '[' <wq-name> ']' |
    '[' <wq-name> <attr-matcher> [ <string-token> | <ident-token> ] <attr-modifier>? ']'
<attr-matcher> = [ '~' | '|' | '^' | '$' | '*' ]? '='
<attr-modifier> = i | s

<pseudo-class-selector> = : <ident-token> |
                          : <function-token> <any-value> )

<pseudo-element-selector> = : <pseudo-class-selector> | <legacy-pseudo-element-selector>
<legacy-pseudo-element-selector> =  : [before | after | first-line | first-letter]

在解释上述语法时,适用以下规则

注意:选择器还受到各种更具体语法约束的限制,遵守上述语法是选择器被视为有效的必要条件,但并非充分条件。有关解析选择器的其他规则,请参阅 § 3.9 无效选择器与错误处理

注意:通常情况下,<pseudo-element-selector> 仅在放置于 <complex-selector> 中最后一个 <compound-selector> 的末尾时才有效。但在某些情况下,它后面可以跟更多的 <pseudo-element-selector><pseudo-class-selector>;但这需根据具体情况进行说明。(例如,用户操作伪类允许在任何 伪元素 之后,树状伪元素允许在 ::slotted() 伪元素之后。)

由于遗留原因,Level 2 的四个伪元素::before::after::first-line::first-letter)可以在其前面仅书写一个 ":" 字符,使其外观看起来像一个 <pseudo-class-selector>

16.1. <forgiving-selector-list><forgiving-relative-selector-list>

出于遗留原因,选择器列表的一般行为是:如果列表中的任何选择器解析失败(例如,因为它使用了新的或特定于 UA 的选择器功能),则整个选择器列表将变为无效。这可能导致难以编写既使用新选择器又能在旧用户代理中正确工作的 CSS。

<forgiving-selector-list> 生成规则则是单独解析列表中的每个选择器,简单地忽略那些解析失败的选择器,以便剩余的选择器仍然可以使用。

注意:样式规则仍然使用常规的、非宽容的选择器列表行为。<forgiving-selector-list> 仅用于 :is():where() 中。虽然它在特殊性方面有一些细微的影响,但在样式规则的选择器外包裹 :is() 可有效地将其“升级”为宽容模式,只要它不包含任何伪元素(伪元素在 :is():where() 中无效)。

在语法上,<forgiving-selector-list> 等同于 <any-value>?。然后它被解析为宽容选择器列表以获得其确切值。

解析为宽容选择器列表,给定输入 input
  1. input解析一个 <complex-real-selector> 列表,并令 selector list 为结果。

  2. 移除 selector list 中所有的失败项和无效选择器,然后返回一个代表 selector list 中剩余项的 <selector-list>。(这可能是空的。)

<forgiving-selector-list> 中的任何无效项(无论是显式无效,通过使用未知选择器或语法,还是仅在上下文中无效,即在无效上下文中使用已知语法)都必须被视为特殊性为零。

注意:<forgiving-selector-list> 故意仅用于 :is():where() 中,不用于任何其他接受选择器参数的选择器。

17. API 钩子

为了辅助编写使用选择器概念的规范,本节定义了几个可以由其他规范调用的 API 钩子。

既然我们有了更严格的 匹配无效选择器 定义,这些钩子还有必要吗?在规范之间协调名词比协调谓词容易得多,而且像 querySelector 返回元素的精确顺序这类细节,在 DOM 规范中定义似乎比在选择器规范中定义更合理。

17.1. 解析选择器

本节定义如何从字符串 source解析选择器。它返回一个复合选择器列表或失败。

  1. selector解析 source 作为 <selector-list> 的结果。如果这返回失败,则它是一个无效选择器;返回失败。
  2. 如果 selector 因任何其他原因(例如包含未声明的命名空间前缀)而成为无效选择器,则返回失败。
  3. 否则,返回 selector

17.2. 解析相对选择器

本节定义如何从字符串 source解析相对选择器。它返回一个复合选择器列表或失败。

  1. selector解析 source 作为 <relative-selector-list> 的结果。如果这返回失败,则它是一个无效选择器;返回失败。
  2. 如果 selector 因任何其他原因(例如包含未声明的命名空间前缀)而成为无效选择器,则返回失败。
  3. 否则,返回 selector

17.3. 针对元素匹配选择器

本节定义如何针对元素匹配选择器

使用此算法的 API 必须提供 selectorelement

调用者可以选择提供

此算法返回成功或失败。

对于给定 selector 中的每个复合选择器(被视为复合选择器列表),按照下一段所述针对 element 匹配该复合选择器。如果匹配对任何复合选择器返回成功,则算法返回成功;否则返回失败。

针对元素匹配复合选择器,需从右向左逐个复合选择器进行处理。此过程递归定义如下

17.4. 针对伪元素匹配选择器

本节定义如何针对伪元素匹配选择器

使用此算法的 API 必须提供 selectorpseudo-element。它们可以选择提供与针对元素匹配选择器算法相同的可选参数。

此算法返回成功或失败。

对于给定 selector 中的每个复合选择器,如果满足以下两个条件

则返回成功。

否则(即,如果 selector 中的任何复合选择器均未发生此情况),则返回失败。

17.5. 针对树匹配选择器

本节定义如何针对树匹配选择器

使用此算法的 API 必须提供选择器,以及一个或多个 root elements,用以指示选择器将搜索的子树。所有的 root elements 必须拥有相同的,否则调用此算法无效。

它们可以选择提供

此算法返回一个(可能为空的)元素列表。

  1. 以一组 candidate elements 开始,即 root elements 及其所有后代元素,除非另有说明,否则按包含阴影的树顺序排序。
  2. 如果提供了 作用域根,则从 candidate elements 中移除不是至少一个 作用域根后代的任何元素。
  3. 初始化 selector match list 为空。
  4. 对于 candidate elements 集合中的每个 element
    1. 如果针对 elementselector 运行针对元素匹配选择器的结果为成功,则将 element 添加到 selector match list
    2. 对于与 element 关联的、允许出现在匹配列表中的每个可能伪元素,如果针对该伪元素和 selector 运行针对伪元素匹配选择器的结果为成功,则将该伪元素添加到 selector match list

      selector match list 中伪元素的相对位置未定义。目前尚无公开此信息的上下文,但在某些信息公开之前,我们最终需要做出决定。

附录 A:关于将源文档和数据映射到元素树的指南

本节是资料性的。

DOM 描述的元素树结构功能强大且有用,但足够通用,可以建模描述基于树的数据(或者如果有适当的解释,甚至可以是基于图的数据)的几乎任何语言。

一些语言(如 HTML)已经拥有从资源生成 DOM 对象的定义明确的过程。如果某种给定的语言没有,则必须定义这样一个过程,以便选择器能够应用于该语言的文档。

至少,文档语言必须定义什么映射到 DOM 的“元素”概念。

节点之间的主要一对多关系——基于树的结构中的父/子,基于图的结构中的元素/邻居——应该反映为元素的子节点。

元素的其他特征应映射到具有与 DOM 中相同特征相似目的的事物

type
如果文档语言中的元素具有某种作为区分不同元素组的“类型”概念,它应该反映为“类型”特征。

如果这种“类型”可以分为“基本”名称和将名称分组到更高级别组的“命名空间”,则后者应反映为“命名空间”特征。否则,元素不应具有“命名空间”特征,整个名称应反映为“类型”特征。

id
如果元素的某些方面在整个文档中起唯一标识符的作用,它应该映射到“id”特征。

注意:虽然 HTML 只允许一个元素拥有单个 ID,但这不应被视为一般限制。ID 的重要特性是每个 ID 应与单个元素关联;单个元素可以有效地拥有多个 ID。

类和属性
元素的那些用于标识元素但通常在文档内元素之间不唯一的方面,应根据它们是等同于“标签”(纯字符串)还是“属性”(名/值对),映射到“类”或“属性”特征。
伪类和伪元素
如果任何元素匹配任何伪类或具有任何伪元素,这必须明确定义。

一些伪类是*语法性*的,如 :has():is(),因此应该始终有效。需要在某处指出这一点。结构伪类可能在子列表有序时始终有效。

例如,JSONSelect 是一个使用选择器从 JSON 文档中提取信息的库。

这种结构足以允许使用选择器对 JSON 文档进行强大而紧凑的查询。

附录 B:为 Web 兼容性而过时但必须的 -webkit- 解析怪癖

测试

本附录是规范性的。

由于遗留的 Web 兼容性约束,期望解析 Web 文档的用户代理必须支持以下功能

附录 C:示例隐私保护 :visited 限制

以往保护用户在 :visited 中隐私的尝试,涉及复杂的限制和行为,以“谎称”链接是否匹配 :visited:link,从而降低恶意站点观察用户访问过哪些无关站点的机会,同时仍允许 :visited 在所有情况下正常工作,帮助用户了解他们已点击过的链接。这最终是一场无法获胜的军备竞赛;即使有这些缓解措施,仍有多种已记录的方法可以提取用户的浏览历史。

本节描述了一种最初在 https://github.com/explainers-by-googlers/Partitioning-visited-links-history 开发和记录的方法,它对用户的浏览历史信息进行了分区,以允许 :visited 仅匹配与站点源本身本可以观察到的导航相对应的链接。通过这种方式,:visited 可以被视为一个普通的伪类,无需任何上述复杂的缓解措施,因为它不会暴露任何该站点在理论上尚未能获取的信息,同时仍尽可能多地为用户保留 :visited有用性

  1. visited history 为一个包含三个信息片段的元组集合

    • 已访问的 URL

    • 发起导航的站点的源 (origin)

    • 包含发起导航的框架的顶级站点的站点 (site)。(这通常与前者相同,但如果用户在 iframe 中点击链接,则可能不同。)

  2. 每当触发页面内部的导航时——例如用户点击链接,或页面上的脚本发起导航——都会向 visited history 添加一个条目,记录导航的目标 URL、包含链接或脚本的页面的源,以及包含该页面的顶级站点的(基于方案的)站点(这可能与前一个源的站点相同)。

    注意:这允许站点查看用户从该站点源内任何地方点击的链接的 :visited 信息。换句话说,任何站点为 A 的 A -> B 导航。

    此外,添加一个记录目标 URL、目标源和目标站点的 visited history 条目。仅针对顶级框架或与顶级框架同源的 iframe 的导航执行此操作。

    注意:这允许站点查看关于其自身页面的 :visited 信息(这已经是站点可观察到的),无论哪个站点发起了到该页面的导航。换句话说,任何站点为 B 的 A -> B 导航。

    注意:值得注意的是,由用户代理的 UI 直接触发的导航,例如在地址栏中输入、点击书签或将链接从其他程序拖入页面,不会添加 visited history 条目。当然,这些仍然可以增加浏览器用于其他目的的已访问站点记录,例如在用户在 URL 栏中输入时建议 URL。

  3. 在确定链接元素是否应匹配 :link:visited 时,仅允许其匹配 :visited(如果链接的目标、包含链接的页面的源以及包含链接的顶级站点与 visited history 中的元组匹配)。

同时包含页面源和顶级站点可以防止多种可能的隐私攻击,例如

18. 变更 (Changes)

18.1. 自 2022 年 11 月 11 日工作草案以来的变更

2022 年 11 月 11 日工作草案以来的重大变更

18.2. 自 2022 年 5 月 7 日工作草案以来的变更

2022 年 5 月 7 日工作草案以来的重大变更

18.3. 自 2018 年 11 月 21 日工作草案以来的变更

2018 年 11 月 21 日工作草案以来的重大变更

18.4. 自 2018 年 2 月 2 日工作草案以来的变更

2018 年 2 月 2 日工作草案以来的重大变更

18.5. 自 2013 年 5 月 2 日工作草案以来的变更

2013 年 5 月 2 日工作草案以来的重大变更包括

注:2018 年 2 月 1 日的草案中意外提交了未完成的工作;2018 年 2 月 2 日撤销了此提交(并修复了一些链接,因为为什么不呢)。

18.6. 自 2012 年 8 月 23 日工作草案以来的变更

2012 年 8 月 23 日工作草案以来的重大变更包括:

18.7. 自 2011 年 9 月 29 日工作草案以来的变更

2011 年 9 月 29 日工作草案以来的重大变更包括:

18.8. 自 Level 3 以来的变更

Level 3 以来的新增内容

19. 致谢

CSS 工作组感谢多年来为前作选择器规范做出贡献的所有人,这些规范构成了本规范的基础。特别感谢以下人员对选择器 Level 4 的具体贡献:L. David Baron, Andrew Fedoniouk, Daniel Glazman, Ian Hickson, Grey Hodge, Lachlan Hunt, Anne van Kesteren, Jason Cranford Teague, Lea Verou。

隐私考量

安全考量

隐私考量也可能被认为会影响安全性。

一致性

文档约定

一致性要求通过描述性断言和 RFC 2119 术语相结合来表达。本文档规范性部分中的关键词“MUST”(必须)、“MUST NOT”(不得)、“REQUIRED”(必需)、“SHALL”(应)、“SHALL NOT”(不应)、“SHOULD”(推荐)、“SHOULD NOT”(不推荐)、“RECOMMENDED”(建议)、“MAY”(可以)和“OPTIONAL”(可选)应按照 RFC 2119 中的描述进行解释。然而,为了可读性,这些词在本文档中不以全大写形式出现。

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

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

这是一个说明性示例。

说明性注释以“Note”一词开头,并使用 class="note" 与规范性文本隔开,如下所示

注意,这是一个说明性注释。

建议(Advisements)是规范性章节,旨在引起特别注意,并使用 <strong class="advisement"> 与其他规范性文本区分开来,如下所示: 用户代理必须提供可访问的替代方案。

测试

与本规范内容相关的测试可记录在“Tests”块中,就像这一个一样。任何此类块都是非规范性的。


一致性类别

本规范为三类一致性定义了一致性要求。

样式表
一份 CSS 样式表
渲染器
一种 用户代理 (UA),它解释样式表的语义并渲染使用它们的文档。
创作工具
一种 用户代理 (UA),用于编写样式表。

如果样式表包含的所有使用本模块定义语法的语句,根据通用 CSS 语法及本模块定义的各功能语法均有效,则该样式表符合本规范。

如果渲染器除了按相应规范解释样式表外,还通过正确解析本规范定义的所有功能并相应地渲染文档来支持这些功能,则该渲染器符合本规范。然而,由于设备限制导致 UA 无法正确渲染文档,并不意味着该 UA 不符合规范。(例如,UA 无需在单色显示器上渲染颜色。)

如果创作工具编写的样式表根据通用 CSS 语法及本模块中各功能的语法是句法正确的,并符合本模块中描述的所有其他样式表一致性要求,则该创作工具符合本规范。

部分实现

为了使作者能够利用前向兼容的解析规则来指定后备值,CSS 渲染器 **必须** 将其无法使用支持级别的任何 @规则、属性、属性值、关键字和其他语法结构视为无效(并 适当忽略)。特别地,用户代理 **不得** 在单一多值属性声明中选择性地忽略不支持的组件值而保留支持的值:如果任何值被视为无效(因为不支持的值必须如此),CSS 要求忽略整个声明。

不稳定和专有特性的实现

为了避免与未来稳定的 CSS 功能发生冲突,CSS 工作组建议在实施不稳定功能和私有扩展遵循最佳实践

非实验性实现

一旦规范达到候选推荐阶段,非实验性实现即可成为可能,实现者应发布他们能够证明根据规范正确实现的任何 CR 级别特性的无前缀实现。

为建立并保持 CSS 在不同实现间的互操作性,CSS 工作组请求非实验性的 CSS 渲染器在发布任何 CSS 功能的无前缀实现之前,向 W3C 提交一份实现报告(并在必要时提交用于该实现报告的测试用例)。提交给 W3C 的测试用例需经 CSS 工作组审阅和修正。

有关提交测试用例和实现报告的详细信息,请访问 CSS 工作组网站 https://w3org.cn/Style/CSS/Test/。问题可发送至 public-css-testsuite@w3.org 邮件列表。

索引

本规范定义的术语

通过引用定义的术语

引用

规范性引用

[BCP47]
A. Phillips, Ed.; M. Davis, Ed.. 语言标识标签. 2009年9月. 最佳当前实践. URL: https://www.rfc-editor.org/rfc/rfc5646
[CSS-DISPLAY-4]
Elika Etemad; Tab Atkins Jr.. CSS 显示模块 Level 4. 2025 年 11 月 6 日. WD. URL: https://w3org.cn/TR/css-display-4/
[CSS-MULTICOL-2]
Florian Rivoal; Rachel Andrew. CSS 多列布局模块 Level 2。2024 年 12 月 19 日。FPWD。URL: https://w3org.cn/TR/css-multicol-2/
[CSS-POSITION-4]
Elika Etemad; Tab Atkins Jr.. CSS 定位布局模块 Level 4。2025 年 10 月 7 日。WD。URL: https://w3org.cn/TR/css-position-4/
[CSS-PSEUDO-4]
Elika Etemad; Alan Stearns. CSS 伪元素模块 Level 4. 2025 年 6 月 27 日. WD. URL: https://w3org.cn/TR/css-pseudo-4/
[CSS-SHADOW-1]
CSS 阴影模块 Level 1。编辑草案。URL: https://drafts.csswg.org/css-shadow-1/
[CSS-TEXT-4]
Elika Etemad; 等. CSS 文本模块 Level 4. 2024 年 5 月 29 日. WD. URL: https://w3org.cn/TR/css-text-4/
[CSS-VALUES-4]
Tab Atkins Jr.; Elika Etemad. CSS 值与单位模块 4 级 (CSS Values and Units Module Level 4). 2024年3月12日. WD. URL: https://w3org.cn/TR/css-values-4/
[CSS-WRITING-MODES-3]
Elika Etemad; Koji Ishii. CSS Writing Modes Level 3. 2019年12月10日. REC. URL: https://w3org.cn/TR/css-writing-modes-3/
[CSS21]
Bert Bos; et al. 层叠样式表 2 级修订版 1 (CSS 2.1) 规范 (Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification). 2011年6月7日. REC. URL: https://w3org.cn/TR/CSS2/
[CSS3NAMESPACE]
Elika Etemad. CSS 命名空间模块 Level 3。2014 年 3 月 20 日。REC。URL: https://w3org.cn/TR/css-namespaces-3/
[CSS3SYN]
Tab Atkins Jr.; Simon Sapin. CSS 语法模块 3 级 (CSS Syntax Module Level 3). 2021年12月24日. CRD. URL: https://w3org.cn/TR/css-syntax-3/
[DOM]
Anne van Kesteren. DOM 标准. Living Standard. URL: https://dom.spec.whatwg.org/
[HTML]
Anne van Kesteren; et al. HTML 标准. Living Standard. URL: https://html.whatwg.cn/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra 标准. Living Standard. URL: https://infra.spec.whatwg.org/
[RFC2119]
S. Bradner. RFC 中用于指示要求级别的关键词. 1997年3月. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[RFC4647]
A. Phillips, Ed.; M. Davis, Ed.. 语言标签匹配。2006 年 9 月。最佳当前实践。URL: https://www.rfc-editor.org/rfc/rfc4647
[SELECT]
Tantek Çelik; et al. 选择器第 3 级. 2018 年 11 月 6 日. REC. URL: https://w3org.cn/TR/selectors-3/
[SELECTORS-4]
Elika Etemad; Tab Atkins Jr.. 选择器第 4 级. 2022 年 11 月 11 日. WD. URL: https://w3org.cn/TR/selectors-4/
[SELECTORS-5]
选择器 Level 5。编辑草案。URL: https://drafts.csswg.org/selectors-5/
[URL]
Anne van Kesteren. URL 标准. 生活标准. URL: https://url.spec.whatwg.org/

参考资料

[CSS-COLOR-5]
Chris Lilley; et al. CSS 颜色模块 Level 5。2026 年 1 月 13 日。WD。URL: https://w3org.cn/TR/css-color-5/
[CSS-DISPLAY-3]
Elika Etemad; Tab Atkins Jr.. CSS Display Module Level 3. 2023年3月30日. CR. URL: https://w3org.cn/TR/css-display-3/
[CSS3UI]
Tantek Çelik; Florian Rivoal. CSS 基础用户界面模块 Level 3 (CSS3 UI)。2018 年 6 月 21 日。REC。URL: https://w3org.cn/TR/css-ui-3/
[CSSOM-1]
Daniel Glazman; Emilio Cobos Álvarez. CSS Object Model (CSSOM). 2021年8月26日. WD. URL: https://w3org.cn/TR/cssom-1/
[CSSSTYLEATTR]
Tantek Çelik; Elika Etemad. CSS 样式属性. 2013 年 11 月 7 日. REC. URL: https://w3org.cn/TR/css-style-attr/
[FULLSCREEN]
Philip Jägenstedt. 全屏 API 标准。现行标准。URL: https://fullscreen.spec.whatwg.org/
[HTML5]
Ian Hickson; et al. HTML5。2018 年 3 月 27 日。REC。URL: https://w3org.cn/TR/html5/
[ITS20]
David Filip; et al. 国际化标签集 (ITS) 2.0 版本。2013 年 10 月 29 日。REC。URL: https://w3org.cn/TR/its20/
[MATHML]
Patrick D F Ion; Robert R Miner. 数学标记语言 (MathML™) 1.01 规范。2023 年 3 月 7 日。REC。URL: https://w3org.cn/TR/REC-MathML/
[MATHML-CORE]
David Carlisle; Frédéric Wang. MathML 核心。2025 年 6 月 24 日。CR。URL: https://w3org.cn/TR/mathml-core/
[PICTURE-IN-PICTURE]
Francois Beaufort. 画中画。2025 年 12 月 2 日。WD。URL: https://w3org.cn/TR/picture-in-picture/
[QUIRKS]
Simon Pieters. 怪异模式标准。现行标准。URL: https://quirks.spec.whatwg.org/
[SVG11]
Erik Dahlström; et al. 可缩放矢量图形 (SVG) 1.1 (第二版). 2011 年 8 月 16 日. REC. URL: https://w3org.cn/TR/SVG11/
[XFORMS11]
John Boyer. XForms 1.1。2009 年 10 月 20 日。REC。URL: https://w3org.cn/TR/xforms11/
[XML-NAMES]
Tim Bray; et al. XML 1.0 中的命名空间(第三版)。2009 年 12 月 8 日。REC。URL: https://w3org.cn/TR/xml-names/
[XML10]
Tim Bray; et al. 可扩展标记语言 (XML) 1.0 (第五版). 2008年11月26日. REC. URL: https://w3org.cn/TR/xml/

问题索引

是否为多值匹配添加逗号分隔语法?例如 [rel ~= next, prev, up, first, last]
作者希望将 :focus 从表单控件传播到其关联的 label 元素;主要反对意见似乎是实现难度。参见 CSSWG 问题 (CSS)WHATWG 问题 (HTML)
既然我们有了更严格的 匹配无效选择器 定义,这些还有必要吗?在规范之间协调名词比协调谓词容易得多,而且像 querySelector 返回元素的精确顺序这样的细节,似乎在 DOM 规范中定义比在选择器规范中定义更合理。
只有 树守从属伪元素 以某种方式得到了类似的处理。
选择器匹配列表 中伪元素的相对位置未定义。目前还没有暴露此信息的上下文,但我们最终需要决定一些事情,在某些东西暴露之前。
有些伪类是*语法性*的,比如 :has():is(),因此应该总是有效的。需要在某处标明这一点。可能结构伪类在子列表有序时总是有效。
语义定义可能应该移回此处。
需要为 XML 定义树结构。