W3C

选择器 3 级

W3C 推荐标准 2018年11月06日

此版本:
https://www.w3.org/TR/2018/REC-selectors-3-20181106/
最新版本:
https://www.w3.org/TR/selectors-3/
之前的版本:
https://www.w3.org/TR/2018/PR-selectors-3-20180911/
选择器的最新版本:
https://www.w3.org/TR/selectors/
编辑草案:
https://drafts.csswg.org/selectors-3/
反馈:
GitHub 上提交问题
编辑:
Tantek Çelik (受邀专家)
Elika J. Etemad (受邀专家)
Daniel Glazman (Disruptive Innovations SARL)
Ian Hickson (Google)
Peter Linss (前编辑, Netscape/AOL)
John Williams (前编辑, Quark, Inc.)

请查看勘误表以了解自发布以来报告的任何错误或问题。


摘要

选择器是与树中的元素匹配的模式,因此是可用于在XML文档中选择节点的几种技术之一。选择器已针对HTML和XML的使用进行了优化,并且设计为可在性能关键的代码中使用。

CSS(层叠样式表)是一种用于描述HTMLXML文档在屏幕、纸张、语音等介质上呈现的语言。CSS 使用选择器将样式属性绑定到文档中的元素。

本文档描述了CSS1[CSS1]CSS2[CSS21]中已经存在的选择器,并进一步为CSS3和可能需要它们的其他语言引入了新选择器。

选择器定义了以下功能:

expression ∗ element → boolean

即,给定一个元素和一个选择器,本规范定义该元素是否与选择器匹配。

这些表达式还可以用于例如通过在子树中的所有元素上评估表达式来选择一组元素或从一组元素中选择单个元素。STTS(简单树转换表),一种用于转换XML树的语言,使用此机制。[STTS3]

本文档的状态

本节描述了本文档在发布时的状态。其他文档可能会取代本文档。在W3C技术报告索引中可以找到当前W3C出版物的列表及本技术报告的最新修订版。

本W3C推荐标准与2018年9月11日的建议推荐标准完全相同,只是状态和模板更新为W3C推荐标准。

本文件已由W3C成员、软件开发人员及其他W3C小组和感兴趣的各方进行了审查,并由主管推荐为W3C推荐标准。它是一个稳定的文件,可以作为参考材料或从其他文档中引用。W3C在制定推荐标准时的作用是引起对规范的关注,并促进其广泛部署。这增强了Web的功能和互操作性。

本文档由CSS工作组作为W3C推荐标准制作。

建议推荐标准是一份已被广泛审查并准备实施的文件。W3C鼓励大家实施本规范,并在2018年10月11日之前通过GitHub问题返回意见。所有问题和评论都已归档,还有一个历史归档

本文件由遵循W3C专利政策的工作组制作。W3C维护了与本工作组交付物相关的任何专利披露的公开列表;该页面还包括披露专利的说明。个人如果实际知道某项专利且认为其中包含基本专利权要求,则必须根据W3C专利政策第6节的规定披露该信息。

本文件受2018年2月1日W3C流程文档的管辖。

一个单独的测试套件实施报告也已提供。

1. 简介

选择器级别 1 和选择器级别 2 定义为在 CSS1CSS2.1 规范中定义的选择器功能的子集, 分别。

1.1. 依赖关系

本规范中的某些功能特定于CSS,或具有CSS特有的限制或规则。在本规范中,这些内容已根据CSS2.1进行了描述。[CSS21]

1.2. 术语

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

附加术语在定义部分中进行了定义。[CSS21] 文档源代码和片段示例以 XML [XML10] 或 HTML [HTML401][HTML5] 语法提供。

1.3. 与 CSS2 的变化

本节为非规范性内容。

CSS2中的选择器与本规范中的选择器之间的主要区别包括:

2. 选择器

本节为非规范性内容,仅总结了以下部分。

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

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

下表总结了选择器的语法:

模式 表示 描述 级别
* 任何元素 通用选择器 2
E 类型为E的元素 类型选择器 1
E[foo] 具有“foo”属性的E元素 属性选择器 2
E[foo="bar"] “foo”属性值完全等于“bar”的E元素 属性选择器 2
E[foo~="bar"] “foo”属性值是一个以空格分隔的值列表,其中之一完全等于“bar”的E元素 属性选择器 2
E[foo^="bar"] “foo”属性值以字符串“bar”开头的E元素 属性选择器 3
E[foo$="bar"] “foo”属性值以字符串“bar”结尾的E元素 属性选择器 3
E[foo*="bar"] “foo”属性值包含子字符串“bar”的E元素 属性选择器 3
E[foo|="en"] “foo”属性具有以连字符分隔的值列表,并以“en”开头(从左边开始)的E元素 属性选择器 2
E:root 文档的根元素E 结构伪类 3
E:nth-child(n) 父元素的第n个子元素E 结构伪类 3
E:nth-last-child(n) 父元素的倒数第n个子元素E 结构伪类 3
E:nth-of-type(n) 其类型的第n个兄弟元素E 结构伪类 3
E:nth-last-of-type(n) 其类型的倒数第n个兄弟元素E 结构伪类 3
E:first-child 父元素的第一个子元素E 结构伪类 2
E:last-child 父元素的最后一个子元素E 结构伪类 3
E:first-of-type 其类型的第一个兄弟元素E 结构伪类 3
E:last-of-type 其类型的最后一个兄弟元素E 结构伪类 3
E:only-child 父元素的唯一子元素E 结构伪类 3
E:only-of-type 其类型的唯一兄弟元素E 结构伪类 3
E:empty 没有子元素(包括文本节点)的E元素 结构伪类 3
E:link
E:visited
作为超链接的源锚点的E元素,其目标尚未访问(:link)或已访问(:visited) 链接伪类 1
E:active
E:hover
E:focus
在某些用户操作期间的E元素 用户操作伪类 1 和 2
E:target 作为引用URI目标的E元素 目标伪类 3
E:lang(fr) 语言为“fr”的E类型元素(文档语言规定了如何确定语言) :lang() 伪类 2
E:enabled
E:disabled
启用或禁用的用户界面元素E UI元素状态伪类 3
E:checked 选中的用户界面元素E(例如单选按钮或复选框) UI元素状态伪类 3
E::first-line E元素的第一个格式化行 ::first-line 伪元素 1
E::first-letter E元素的第一个格式化字母 ::first-letter 伪元素 1
E::before E元素之前生成的内容 ::before 伪元素 2
E::after E元素之后生成的内容 ::after 伪元素 2
E.warning 类为“warning”的E元素(文档语言规定了如何确定类) 类选择器 1
E#myid ID为“myid”的E元素 ID选择器 1
E:not(s) 不匹配简单选择器s的E元素 否定伪类 3
E F E元素的后代F元素 后代组合器 1
E > F E元素的子元素F 子代组合器 2
E + F 紧接在E元素之后的F元素 相邻兄弟组合器 2
E ~ F 紧接在E元素之后的F元素 普通兄弟组合器 3

3. 区分大小写

在ASCII范围内,所有选择器语法都是不区分大小写的(即[a-z]和[A-Z]是等效的),除了那些不受选择器控制的部分。选择器中文档语言元素名称、属性名称和属性值的大小写敏感性取决于文档语言。例如,在HTML中,元素名称不区分大小写,但在XML中,它们区分大小写。命名空间前缀的大小写敏感性在[CSS3NAMESPACE]中定义。

4. 选择器语法

选择器是由一个或多个简单选择器序列组成的链条,它们由组合器分隔。一个伪元素可以附加到选择器中最后一个简单选择器序列的末尾。

简单选择器序列是一串简单选择器,它们之间没有组合器分隔。它总是以类型选择器通用选择器开头。序列中不允许使用其他类型选择器或通用选择器。

简单选择器可以是类型选择器通用选择器属性选择器类选择器ID选择器伪类

组合器包括:空格、“大于号”(U+003E,>)、“加号”(U+002B,+)和“波浪号”(U+007E,~)。空格可以出现在组合器与其周围的简单选择器之间。空格中只包含“空格”(U+0020)、“制表符”(U+0009)、“换行符”(U+000A)、“回车符”(U+000D)和“换页符”(U+000C)。其他类似空格的字符,如“em-space”(U+2003)和“汉字空格”(U+3000),从不属于空格的一部分。

文档树中由选择器表示的元素是选择器的主语。由单个简单选择器序列组成的选择器表示满足其要求的任何元素。将另一个简单选择器序列和组合器前置于一个序列之前会增加额外的匹配约束,因此选择器的主语始终是由最后一个简单选择器序列表示的元素的子集。

空选择器(不包含简单选择器序列和伪元素)是无效选择器

选择器中的字符可以按照与CSS相同的转义规则用反斜杠进行转义。[CSS21]

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

5. 选择器组

用逗号分隔的选择器列表表示列表中每个单独选择器选择的所有元素的并集。(逗号为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的规则会被丢弃。)

6. 简单选择器

6.1. 类型选择器

类型选择器是使用CSS 合格名称语法编写的文档语言元素类型名称。[CSS3NAMESPACE]。类型选择器表示文档树中元素类型的一个实例。

示例:

以下选择器表示文档树中的h1元素:

h1

6.1.1. 类型选择器和命名空间

类型选择器允许使用可选的命名空间组件:可以在元素名称前附加一个之前声明的命名空间前缀,并通过命名空间分隔符“竖线”(U+007C,|)分隔。(参见例如[XML-NAMES]了解在XML中使用命名空间。)

命名空间组件可以为空(命名空间分隔符前没有前缀),表示选择器仅代表没有命名空间的元素。

可以使用星号作为命名空间前缀,表示选择器代表任何命名空间中的元素(包括没有命名空间的元素)。

没有命名空间组件(没有命名空间分隔符)的元素类型选择器表示不考虑元素命名空间的元素(相当于“*|”),除非已为命名空间选择器声明默认命名空间(例如在CSS中,在样式表中)。如果已声明默认命名空间,则此类选择器将仅表示默认命名空间中的元素。

包含未为命名空间选择器声明过的命名空间前缀的类型选择器是无效选择器。

在支持命名空间的客户端中,元素类型选择器的名称部分(如果存在,则是命名空间分隔符后的部分)只会与元素的本地部分匹配合格名称

总结如下:

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 }  /* 第一条规则 */
 foo|* { color: yellow } /* 第二条规则 */
 |h1 { color: red }      /* ...*/
 *|h1 { color: green }
 h1 { color: green }

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

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

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

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

由于未定义默认命名空间,因此最后一条规则等同于第四条规则。

6.2. 通用选择器

通用选择器,写作CSS 合格名称 [CSS3NAMESPACE],其本地名称为星号(* U+002A),代表任何元素类型的合格名称。如果未为选择器指定默认命名空间,则它代表文档树中任何命名空间(包括没有命名空间的元素)中的任何单个元素。如果已指定默认命名空间,请参见下文通用选择器和命名空间

如果由*表示的通用选择器(即没有命名空间前缀)不是简单选择器序列的唯一组件或紧跟在伪元素之后,则可以省略*,并暗示通用选择器的存在。

示例:

注意:建议不要省略*,因为这会减少例如div :first-childdiv:first-child之间的潜在混淆。在这种情况下,div *:first-child更具可读性。

6.2.1. 通用选择器和命名空间

通用选择器允许使用可选的命名空间组件。使用方式如下:

ns|*
命名空间 ns 中的所有元素
*|*
所有元素
|*
没有命名空间的所有元素
*
如果未指定默认命名空间,这相当于 *|*。否则相当于 ns|*,其中 ns 是默认命名空间。

包含未声明的命名空间前缀的通用选择器是无效选择器。

6.3. 属性选择器

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

6.3.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伪类

属性值必须是 CSS 标识符字符串[CSS21] 选择器中属性名称和值的大小写敏感性取决于文档语言。

示例:

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

h1[title]

在以下示例中,选择器表示一个span元素,其class属性的值正好为"example":

span[class="example"]

可以使用多个属性选择器来表示元素的多个属性,或对同一属性的多个条件。在此,选择器表示一个span元素,其hello属性的值正好为"Cleveland",并且其goodbye属性的值正好为"Columbus":

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

以下 CSS 规则说明了"="和"~="之间的区别。第一个选择器将匹配例如具有rel属性值为"copyright copyleft copyeditor"的a元素。第二个选择器只会匹配href属性值正好为"http://www.w3.org/"的a元素。

a[rel~="copyright"] { ... }
a[href="http://www.w3.org/"] { ... }

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

a[hreflang=fr]

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

a[hreflang|="en"]

以下选择器表示DIALOGUE元素,只要它的character属性具有两种不同的值之一:

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

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

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

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

属性值必须是 CSS 标识符字符串[CSS21] 选择器中属性名称的大小写敏感性取决于文档语言。

示例:

以下选择器表示引用图像的 HTML object

object[type^="image/"]

以下选择器表示href属性值以“.html”结尾的 HTML 锚点a

a[href$=".html"]

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

p[title*="hello"]

6.3.3. 属性选择器和命名空间

属性选择器中的属性名称以CSS 合格名称形式给出:可以在属性名称前附加一个之前声明的命名空间前缀,并通过命名空间分隔符“竖线” (|) 分隔。根据 XML 推荐规范中的命名空间,默认命名空间不适用于属性,因此没有命名空间组件的属性选择器仅适用于没有命名空间的属性(相当于"|attr")。可以使用星号作为命名空间前缀,表示选择器将匹配所有属性名称,而不考虑属性的命名空间。

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

CSS 示例:

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

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

第二条规则将匹配具有"att"属性的所有元素,而不考虑属性的命名空间(包括没有命名空间的情况)。

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

6.3.4. 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] { /*... 默认属性设置 ...*/ }
EXAMPLE[radix=octal]   { /*... 其他设置...*/ }

第一条规则可能不会匹配radix属性由默认设置而非显式设置的元素。为了捕获所有情况,必须删除默认值的属性选择器:

EXAMPLE                { /*... 默认属性设置 ...*/ }
EXAMPLE[radix=octal]   { /*... 其他设置...*/ }

在此,因为选择器EXAMPLE[radix=octal]比单独的类型选择器更具体,因此第二条规则中的样式声明将覆盖第一条规则中的声明,用于radix属性值为"octal"的元素。必须小心确保所有仅适用于默认情况下的属性声明都在非默认情况下的样式规则中被覆盖。

6.4. 类选择器

在使用HTML时,作者可以使用“句点”符号(也称为“full stop”,U+002E,.)作为表示class属性的替代表示法~=。因此,对于HTML,div.valuediv[class~=value]具有相同的含义。属性值必须紧跟在句点符号(.)之后。

如果UA具有命名空间特定的知识,能够确定哪个属性是相应命名空间的“class”属性,则UA可以在XML文档中应用使用句点(.)符号的选择器。一个这样的命名空间特定知识的示例是特定命名空间规范中的描述(例如,SVG 1.1 [SVG11] 描述了 SVG 的 class 属性 及UA应该如何解释它,类似地,MathML [MATHML3] 描述了 MathML 的 class 属性。)

CSS示例:

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

*.pastoral { color: green }  /* 所有 class~=pastoral 的元素 */

或仅

.pastoral { color: green }  /* 所有 class~=pastoral 的元素 */

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

H1.pastoral { color: green }  /* class~=pastoral 的 H1 元素 */

根据这些规则,下面的第一个H1实例将不会是绿色的文本,而第二个将是绿色的文本:

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

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

p.pastoral.marine { color: green }

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

注意:由于CSS赋予class属性相当大的权力,作者可以设计他们自己的“文档语言”,其基于几乎没有相关展示的元素(例如HTML中的DIVSPAN),并通过class属性分配样式信息。作者应避免这种做法,因为文档语言的结构元素通常具有公认和接受的含义,而作者定义的类可能没有。

注意:如果一个元素有多个类属性,在搜索类之前,其值必须用空格连接在一起。截至目前,工作组尚未意识到可以达到这种情况的任何方式,因此,此行为在本规范中明确为非规范性的。

6.5. ID选择器

文档语言可能包含声明为ID类型的属性。ID类型属性的特殊之处在于,在符合规范的文档中,无论承载它们的元素类型如何,不能有两个具有相同值的ID类型属性;无论文档语言是什么,ID类型属性都可以用来唯一标识其元素。在HTML中,所有ID属性都命名为"id";XML应用程序可能会以不同的方式命名ID属性,但相同的限制适用。

文档语言的ID类型属性允许作者为文档树中的一个元素实例分配标识符。ID选择器包含一个“井号”(U+0023,#),紧跟在ID值之后,该值必须是CSS 标识符。ID选择器表示具有与ID选择器中的标识符匹配的标识符的元素实例。

选择器不指定UA如何知道元素的ID类型属性。UA可以例如读取文档的DTD,将信息硬编码或询问用户。

示例:

以下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、DOM、XML DTDs和命名空间特定的知识来实现。

6.6. 伪类

引入伪类的概念是为了允许基于文档树之外的信息或无法使用其他简单选择器表达的信息进行选择。

伪类总是由“冒号”(:)后跟伪类名称,后面可选地跟一个括号内的值组成。

伪类允许出现在选择器包含的所有简单选择器序列中。伪类可以出现在简单选择器序列中的任何位置,在前导类型选择器或通用选择器(可能省略)之后。伪类名称不区分大小写。有些伪类是互斥的,而另一些可以同时应用于同一个元素。伪类可以是动态的,这意味着元素在用户与文档交互时可能获得或失去伪类。

6.6.1. 动态伪类

动态伪类根据元素的名称、属性或内容以外的特征对元素进行分类,原则上这些特征无法从文档树中推导出。

动态伪类不会出现在文档源或文档树中。

用户代理通常会将未访问的链接与以前访问过的链接显示得不同。选择器提供了伪类:link:visited来区分它们:

在一段时间后,用户代理可能会选择将访问过的链接返回到(未访问)“:link”状态。

这两种状态是互斥的。

示例:

以下选择器表示已访问且带有external类的链接:

a.external:visited

注意:样式表作者可能会滥用:link 和 :visited 伪类,在未经用户同意的情况下确定用户访问过哪些网站。

因此,UA 可能会将所有链接视为未访问的链接,或实施其他措施,以在不同地呈现已访问和未访问链接的同时保护用户的隐私。

6.6.1.2. 用户操作伪类 :hover, :active 和 :focus

交互式用户代理有时会根据用户操作更改渲染。选择器提供了三个伪类,用于选择用户正在操作的元素。

文档语言或实现可能对哪些元素可以变为:active或获得:focus有特定限制。

这些伪类不是互斥的。一个元素可以同时匹配多个伪类。

选择器没有定义一个元素的父元素是否也是“:active”或“:hover”状态。

注意:如果元素处于“:hover”状态,因为其子元素被指针设备指定,那么可能会有一个不在指针设备下的元素也应用“:hover”。

示例:

a:link    /* 未访问的链接 */
a:visited /* 已访问的链接 */
a:hover   /* 用户悬停 */
a:active  /* 活动链接 */

动态伪类组合的示例:

a:focus
a:focus:hover

最后一个选择器匹配同时处于伪类 :focus 和伪类 :hover 的 a 元素。

注意:一个元素可以同时是“:visited”和“:active”(或“:link”和“:active”)。

6.6.2. 目标伪类 :target

某些 URI 指向资源中的一个位置。这种 URI 以“井号”(#)结尾,后跟锚点标识符(称为片段标识符)。

带有片段标识符的 URI 链接到文档中的某个元素,该元素称为目标元素。例如,这里有一个指向 HTML 文档中名为 section_2 的锚点的 URI:

http://example.com/html/top.html#section_2

目标元素可以通过 :target 伪类表示。如果文档的 URI 没有片段标识符,则该文档没有目标元素。

示例:

p.note:target

此选择器表示类notep元素,该元素是引用URI的目标元素。

CSS 示例:

在此,如果存在目标元素,使用 :target 伪类将目标元素设置为红色并在其前面放置一张图片:

*:target { color : red }
*:target::before { content : url(target.png) }

6.6.3. 语言伪类 :lang

如果文档语言指定了如何确定元素的自然语言,则可以编写基于其语言表示元素的选择器。例如,在 HTML [HTML401] 中,语言由 lang 属性和可能的信息(如 meta 元素或协议如 HTTP 头)组合确定。XML 使用名为 xml:lang 的属性,可能还存在其他文档语言特定的方法来确定语言。

伪类 :lang(C) 表示处于语言 C 的元素。元素是否由 :lang() 选择器表示,仅基于元素的语言值(如果需要,规范化为 BCP 47 语法)是否等于标识符 C,或是否以标识符 C 开头并紧跟 "-"(U+002D)。在 ASCII 范围内,C 与元素的语言值的匹配是大小写不敏感的。标识符 C 不必是有效的语言名称。

C 必须是有效的 CSS 标识符 [CSS21],且不能为空。(否则,选择器无效。)

注意:建议文档和协议使用 BCP 47 [BCP47] 或其后续版本中的代码,以及在基于 XML 的文档中通过 "xml:lang" 属性指示语言 [XML10]。参见 "FAQ: 两个字母或三个字母的语言代码。"

示例:

以下两个选择器表示在比利时法语或德语中的 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>

6.6.4. UI 元素状态伪类

6.6.4.1. :enabled 和 :disabled 伪类

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

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

启用状态、禁用状态以及用户界面元素的定义取决于具体的语言。在典型的文档中,大多数元素既不匹配 :enabled,也不匹配 :disabled

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

6.6.4.2. :checked 伪类

单选按钮和复选框元素可以由用户切换。一些菜单项在用户选择它们时被“选中”。当这些元素被切换为“开”时,:checked 伪类适用。虽然 :checked 伪类本质上是动态的,可以通过用户操作改变,但由于它也可以基于文档中的语义属性,因此适用于所有媒体。例如,:checked 伪类最初适用于具有 HTML4 中描述的 selectedchecked 属性的元素,但用户当然可以将这些元素切换为“关”,此时 :checked 伪类将不再适用。

6.6.4.3. :indeterminate 伪类

注意:单选按钮和复选框元素可以由用户切换,但有时会处于不确定状态,既未选中也未取消选中。这可能是由于元素属性或 DOM 操作导致的。

本规范的未来版本可能会引入一个 :indeterminate 伪类,适用于这些元素。

6.6.5. 结构性伪类

选择器引入了结构性伪类的概念,以便基于存在于文档树中的额外信息进行选择,但这些信息不能通过其他简单选择器或组合器表示。

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

6.6.5.1. :root 伪类

:root 伪类表示文档的根元素。在 HTML 4 中,这始终是 HTML 元素。

6.6.5.2. :nth-child() 伪类

:nth-child(an+b) 伪类表示一个元素,该元素在文档树中有 an+b-1 个同级元素位于其之前,对于任何正整数或零值的 n 都有效。它不需要有父元素。对于 ab 大于零的值,这实际上将元素的子元素分为 a 个元素的组(最后一组取余数),并选择每组的第 b 个元素。例如,这允许选择器选择表中的每隔一行,并可以用于在四个周期中交替更改段落文本的颜色。ab 的值必须是整数(正数、负数或零)。元素的第一个子元素的索引为1。

此外,:nth-child() 还可以接受 ‘odd’ 和 ‘even’ 作为参数。‘odd’ 的含义与 2n+1 相同,‘even’ 的含义与 2n 相同。

:nth-child() 的参数必须符合以下语法,其中 INTEGER 与令牌 [0-9]+ 匹配,其余的令牌化由第10.2节中的 词法扫描器 提供:

nth
  : S* [ ['-'|'+']? INTEGER? {N} [ S* ['-'|'+'] S* INTEGER ]? |
         ['-'|'+']? INTEGER | {O}{D}{D} | {E}{V}{E}{N} ] S*
  ;

示例:

tr:nth-child(2n+1) /* 代表 HTML 表的每一奇数行 */
tr:nth-child(odd)  /* 同上 */
tr:nth-child(2n+0) /* 代表 HTML 表的每一偶数行 */
tr:nth-child(even) /* 同上 */

/* 在 CSS 中交替段落颜色 */
p:nth-child(4n+1) { color: navy; }
p:nth-child(4n+2) { color: green; }
p:nth-child(4n+3) { color: maroon; }
p:nth-child(4n+4) { color: purple; }

b 值前面有负号时,表达式中的 "+" 字符必须移除(实际上用表示 b 的负值的 "-" 字符替换)。

示例:

:nth-child(10n-1)  /* 代表第9、第19、第29个元素 */
:nth-child(10n+9)  /* 同上 */
:nth-child(10n+-1) /* 语法上无效,将被忽略 */

a=0 时,an 部分无需包含(除非 b 部分已经被省略)。当未包含 anb 为非负值时,+ 符号可以省略。在这种情况下,语法简化为 :nth-child(b)

示例:

foo:nth-child(0n+5)   /* 表示 foo 元素为其父元素的第5个子元素 */
foo:nth-child(5)      /* 同上 */

a=1 或 a=-1 时,规则中的 1 可以省略。

示例:

以下选择器因此是等效的:

bar:nth-child(1n+0)   /* 代表所有 bar 元素,特异性 (0,1,1) */
bar:nth-child(n+0)    /* 同上 */
bar:nth-child(n)      /* 同上 */
bar                   /* 同上但特异性较低 (0,0,1) */

如果 b=0,则选择每 a 个元素中的每一个。在这种情况下,+b(或 -b)部分可以省略,除非 a 部分已经被省略。

示例:

tr:nth-child(2n+0) /* 代表 HTML 表的每一偶数行 */
tr:nth-child(2n) /* 同上 */

允许在 "(" 之后,")" 之前,以及 "+" 或 "-" 两侧存在空白字符,若两者都存在。

包含空白的有效示例:

:nth-child( 3n + 1 )
:nth-child( +3n - 2 )
:nth-child( -n+ 6)
:nth-child( +6 )

包含空白的无效示例:

:nth-child(3 n)
:nth-child(+ 2n)
:nth-child(+ 2)

如果 ab 都等于零,则伪类在文档树中不代表任何元素。

a 的值可以是负数,但只有 an+b 的正值,针对 n≥0 的情况下,才能代表文档树中的某个元素。

示例:

html|tr:nth-child(-n+6)  /* 表示 XHTML 表的前6行 */
6.6.5.3. :nth-last-child() 伪类

:nth-last-child(an+b) 伪类表示一个元素,该元素在文档树中有 an+b-1 个同级元素位于其之后,对于任何正整数或零值的 n 都有效。它不需要有父元素。有关其参数的语法,请参见 :nth-child() 伪类。它还接受 ‘even’ 和 ‘odd’ 作为参数。

示例:

tr:nth-last-child(-n+2)    /* 代表 HTML 表的最后两行 */

foo:nth-last-child(odd)    /* 代表其父元素中的所有奇数 foo 元素,从最后一个开始计数 */
6.6.5.4. :nth-of-type() 伪类

:nth-of-type(an+b) 伪类表示一个元素,该元素在文档树中有 an+b-1 个具有相同扩展元素名称的同级元素位于其之前,对于任何零值或正整数的 n 都有效。它不需要有父元素。有关其参数的语法,请参见 :nth-child() 伪类。它还接受 ‘even’ 和 ‘odd’ 作为参数。

CSS 示例:

这允许作者交替排列浮动图像的位置:

img:nth-of-type(2n+1) { float: right; }
img:nth-of-type(2n) { float: left; }
6.6.5.5. :nth-last-of-type() 伪类

:nth-last-of-type(an+b) 伪类表示一个元素,该元素在文档树中有 an+b-1 个具有相同扩展元素名称的同级元素位于其之后,对于任何零值或正整数的 n 都有效。它不需要有父元素。有关其参数的语法,请参见 :nth-child() 伪类。它还接受 ‘even’ 和 ‘odd’ 作为参数。

示例:

要表示 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)
6.6.5.6. :first-child 伪类

:nth-child(1) 相同。:first-child 伪类表示作为同级元素列表中第一个的元素。

示例:

以下选择器表示作为 div 元素第一个子元素的 p 元素:

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 是任何元素的第一个子元素 */
a:first-child /* 相同(假设 a 不是根元素) */
6.6.5.7. :last-child 伪类

:nth-last-child(1) 相同。:last-child 伪类表示作为同级元素列表中最后一个的元素。

示例:

以下选择器表示作为有序列表 ol 中最后一个子元素的列表项 li

ol > li:last-child
6.6.5.8. :first-of-type 伪类

:nth-of-type(1) 相同。:first-of-type 伪类表示作为同级元素中第一个同类型元素的元素。

示例:

以下选择器表示定义列表 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>
6.6.5.9. :last-of-type 伪类

:nth-last-of-type(1) 相同。:last-of-type 伪类表示作为同级元素中最后一个同类型元素的元素。

示例:

以下选择器表示表行 tr 的最后一个数据单元格 td

tr > td:last-of-type
6.6.5.10. :only-child 伪类

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

6.6.5.11. :only-of-type 伪类

:only-of-type 伪类表示没有同类型兄弟姐妹的元素。与 :first-of-type:last-of-type:nth-of-type(1):nth-last-of-type(1) 相同,但特异性较低。

6.6.5.12. :empty 伪类

:empty 伪类表示没有任何子元素的元素。在文档树中,只有元素节点和内容节点(如 DOM [DOM-LEVEL-3-CORE] 文本节点、CDATA 节点和实体引用)其数据长度非零时才会被认为影响空状态;注释、处理指令和其他节点不会影响元素是否被认为是空的。

示例:

p:empty 是以下片段的有效表示:

<p></p>

foo:empty 不能有效表示以下片段:

<foo>bar</foo>
<foo><bar>bla</bar></foo>
<foo>this is not <bar>:empty</bar></foo>

6.6.6. 空白

本节故意留空。(本节之前定义了 :contains() 伪类。)

6.6.7. 否定伪类

否定伪类 :not(X) 是一种功能性符号,接受简单选择器(不包括否定伪类本身)作为参数。它表示不被其参数表示的元素。

否定伪类不能嵌套;:not(:not(...)) 是无效的。此外,由于伪元素不是简单选择器,因此它们不能作为 :not() 的有效参数。

示例:

以下选择器匹配 HTML 文档中所有未禁用的 button 元素。

button:not([DISABLED])

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

*:not(FOO)

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

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

默认命名空间声明不会影响否定伪类的参数,除非该参数是通用选择器或类型选择器。

示例:

假设默认命名空间绑定到 "http://example.com/",则以下选择器表示不在该命名空间中的所有元素:

*|*:not(*)

以下选择器匹配任何未被悬停的元素,无论其命名空间如何。特别是,它不仅限于匹配默认命名空间中未被悬停的元素,而当不在默认命名空间中的元素被悬停时,它们也不会匹配规则。

*|*:not(:hover)

注意::not() 伪类允许编写无用的选择器。例如 :not(*|*),它不表示任何元素,或者 foo:not(bar),它等效于 foo,但具有更高的特异性。

7. 伪元素

伪元素创建了关于文档树的抽象,超出了文档语言所指定的范围。例如,文档语言不提供访问元素内容的首字母或首行的机制。伪元素允许作者引用这些原本无法访问的信息。伪元素还可以为作者提供引用源文档中不存在的内容的方式(例如 ::before::after 伪元素可以访问生成的内容)。

伪元素由两个冒号(::)加上伪元素的名称组成。

当前文档引入了此 :: 表记法,以区分伪类和伪元素。为了与现有样式表兼容,用户代理还必须接受在 CSS 第 1 和第 2 级中引入的伪元素的旧单冒号表记法(即 :first-line:first-letter:before:after)。此兼容性不适用于本规范中引入的新伪元素。

每个选择器中只能出现一个伪元素,并且如果存在伪元素,它必须出现在表示选择器主体的简单选择器序列之后。注意:未来版本的本规范可能允许每个选择器中使用多个伪元素。

7.1. ::first-line 伪元素

::first-line 伪元素描述了元素的第一行格式化内容。

CSS 示例:

p::first-line { text-transform: uppercase }

上述规则的含义是“将每个 p 元素的第一行字母更改为大写”。

选择器 p::first-line 不匹配任何实际文档元素。它匹配的是符合要求的用户代理将在每个 p 元素的开头插入的伪元素。

请注意,第一行的长度取决于多个因素,包括页面的宽度、字体大小等。因此,普通的 HTML 段落可能如下所示:

<P>This is a somewhat long HTML
paragraph that will be broken into several
lines. The first line will be identified
by a fictional tag sequence. The other lines
will be treated as ordinary lines in the
paragraph.</P>

其行的分割方式如下:

THIS IS A SOMEWHAT LONG HTML PARAGRAPH THAT
will be broken into several lines. The first
line will be identified by a fictional tag
sequence. The other lines will be treated as
ordinary lines in the paragraph.

用户代理可能会“重写”此段落,以包含::first-line虚构标签序列。此虚构标签序列有助于显示属性的继承。

<P><P::first-line> This is a somewhat long HTML
paragraph that </P::first-line> will be broken into several
lines. The first line will be identified
by a fictional tag sequence. The other lines
will be treated as ordinary lines in the
paragraph.</P>

如果伪元素拆分了实际元素,所需效果通常可以通过关闭然后重新打开元素的虚构标签序列来描述。因此,如果我们使用 span 元素标记前面的段落:

<P><SPAN class="test"> This is a somewhat long HTML
paragraph that will be broken into several
lines.</SPAN> The first line will be identified
by a fictional tag sequence. The other lines
will be treated as ordinary lines in the
paragraph.</P>

用户代理可以在插入::first-line 伪元素的虚构标签序列时,模拟 span 的开始和结束标签。

<P><P::first-line><SPAN class="test"> This is a
somewhat long HTML
paragraph that will </SPAN></P::first-line><SPAN class="test"> be
broken into several
lines.</SPAN> The first line will be identified
by a fictional tag sequence. The other lines
will be treated as ordinary lines in the
paragraph.</P>

7.1.1. CSS 中的首行格式化定义

在 CSS 中,::first-line 伪元素只能在附加到块状容器(例如块框、行内块、表格标题或表格单元格)时生效。在这种情况下,它指的是该容器的首行格式化内容。

元素的首行格式化内容可能出现在同一流中的块级后代中(即由于浮动或定位而不脱离文档流的块级后代)。例如,在 <DIV><P>This line...</P></DIV> 中,DIV 的第一行是 P 的第一行(假设 PDIV 均为块级元素)。

表格单元格或行内块的第一行不能是祖先元素的首行格式化内容。因此,在 <DIV><P STYLE="display: inline-block">Hello<BR>Goodbye</P> etcetera</DIV> 中,DIV 的首行格式化内容不是“Hello”行。

注意:注意,此片段中的 p 的第一行:<p><br>First... 不包含任何字母(假设 br 在 HTML 4 中的默认样式)。“First”一词不在首行格式化内容中。

用户代理应表现得好像 ::first-line 伪元素的虚构开始标签嵌套在最内部的封闭块级元素之内。(由于 CSS1 和 CSS2 在此案例中未作说明,作者不应依赖此行为。)例如,以下段落的虚构标签序列为:

<DIV>
  <P>第一段</P>
  <P>第二段</P>
</DIV>

其虚构标签序列为:

<DIV>
  <P><DIV::first-line><P::first-line>First paragraph</P::first-line></DIV::first-line></P>
  <P><P::first-line>Second paragraph</P::first-line></P>
</DIV>

::first-line 伪元素类似于行内级元素,但有某些限制。以下 CSS 属性适用于 ::first-line 伪元素:字体属性、颜色属性、背景属性、‘word-spacing’、‘letter-spacing’、‘text-decoration’、‘text-transform’、‘line-height’。用户代理也可能应用其他属性。

在 CSS 继承过程中,发生在第一行上的子元素部分仅从 ::first-line 伪元素继承适用于 ::first-line 伪元素的属性。对于所有其他属性,继承自首行伪元素的非伪元素父元素。(未出现在首行中的子元素部分总是从该子元素的父元素继承。)

7.2. ::first-letter 伪元素

::first-letter 伪元素表示元素的第一个字母,如果该字母之前没有任何其他内容(例如图像或行内表格)在其行上。::first-letter 伪元素可用于“首字母大写”和“首字下沉”,这是常见的排版效果。

标点符号(即在 Unicode 中定义的“开括号”(Ps)、“闭括号”(Pe)、“首括号”(Pi)、“尾括号”(Pf)和“其他”(Po)标点符号类中的字符)如果位于第一个字母之前或之后,应包含在内。[UNICODE]

引用符号应包含在首字母之前。

::first-letter 也适用于第一个字母实际上是数字的情况,例如“67 million dollars is a lot of money.”中的“6”。

注意:在某些情况下,::first-letter 伪元素应包含不仅仅是行上的第一个非标点字符。例如,组合字符必须与其基字符保持在一起。此外,一些语言可能对如何处理某些字母组合有特定规则。用户代理对 ::first-letter 的定义应至少包括 UAX29 定义的默认字形簇,并且可以根据需要包含更多内容。例如,在荷兰语中,如果字母组合“ij”出现在元素的开头,则两个字母都应被视为 ::first-letter 伪元素的一部分。[UAX29]

如果形成 ::first-letter 的字母不在同一元素中,例如 <p>‘<em>T... 中的“‘T”,用户代理可以从其中一个元素、两个元素或根本不创建伪元素来创建 ::first-letter 伪元素。

同样,如果块的首字母不在行的开头(例如由于双向重排),则用户代理可能不会创建伪元素。

示例:

以下 CSS 和 HTML 示例说明了重叠伪元素如何相互作用。每个 P 元素的首字母将为绿色,字体大小为 ‘24pt’。其余的第一行格式化内容将为‘blue’,而段落的其余部分将为‘red’。

p { color: red; font-size: 12pt }
p::first-letter { color: green; font-size: 200% }
p::first-line { color: blue }

<P>Some text that ends up on two lines</P>

假设在“ends”一词之前会发生换行,这段落的虚构标签序列可能为:

<P>
<P::first-line>
<P::first-letter>
S
</P::first-letter>ome text that
</P::first-line>
ends up on two lines
</P>

请注意,::first-letter 元素位于 ::first-line 元素内部。::first-line 上设置的属性将被 ::first-letter 继承,但如果在 ::first-letter 上设置了相同的属性,则会被覆盖。

首字母必须出现在第一行格式化内容中。例如,在此 HTML 片段中:<p><br>First... 第一行不包含任何字母,::first-letter 不匹配任何内容(假设 br 在 HTML 4 中的默认样式)。特别是,它不匹配“First”的“F”。

7.2.1. 在 CSS 中的应用

在 CSS 中,::first-letter 伪元素适用于块状容器,如块级元素、列表项、表格单元格、表格标题和行内块级元素。注意:本规范的未来版本可能会允许该伪元素应用于更多的显示类型。

::first-letter 伪元素可以与所有包含文本的元素一起使用,或与具有包含文本的后代的元素一起使用。用户代理应表现得好像 ::first-letter 伪元素的虚构开始标签位于元素的第一个文本之前,即使该第一个文本位于后代元素中。

示例:

此 HTML 片段的虚构标签序列为:

<div>
<p>第一个文本。

是:

<div>
<p><div::first-letter><p::first-letter>第</...></...>一个文本。

在 CSS 中,表格单元格或行内块级元素的第一个字母不能是祖先元素的第一个字母。因此,在 <DIV><P STYLE="display: inline-block">Hello<BR>Goodbye</P> etcetera</DIV> 中,DIV 的第一个字母不是字母 “H”。事实上,DIV 没有第一个字母。

如果一个元素是列表项(‘display: list-item’),则::first-letter 适用于标记之后主框中的第一个字母。用户代理可以忽略具有‘list-style-position: inside’ 的列表项上的 ::first-letter。如果一个元素有::before::after内容,::first-letter 适用于包括该内容的元素的第一个字母。

示例:

在规则 p::before {content: "Note: "} 之后,选择器 p::first-letter 匹配 “Note” 的 “N”。

在 CSS 中,如果‘float’ 属性为‘none’,::first-line 伪元素类似于行内级元素;否则,它类似于浮动元素。以下属性适用于 ::first-letter 伪元素:字体属性、‘text-decoration’、‘text-transform’、‘letter-spacing’、‘word-spacing’(在适用时)、‘line-height’、‘float’、‘vertical-align’(仅当‘float’为‘none’时)、边距属性、填充属性、边框属性、颜色属性、背景属性。用户代理也可能应用其他属性。为了允许用户代理渲染排版上正确的首字下沉或首字大写,用户代理可以基于字母的形状选择行高、宽度和高度,不同于普通元素。

示例:

此 CSS 和 HTML 示例展示了首字大写的可能渲染。注意,‘line-height’继承自 ::first-letter 伪元素是 1.1,但在此示例中,用户代理计算了第一个字母的高度,因此它不会在前两行之间造成任何不必要的空白。还要注意,首字母的虚构开始标签位于span内,因此第一个字母的字体重量为正常,而不是span中的加粗:

p { line-height: 1.1 }
p::first-letter { font-size: 3em; font-weight: normal }
span { font-weight: bold }
...
<p><span>Het hemelsche</span> gerecht heeft zich ten lange lesten<br>
Erbarremt over my en mijn benaeuwde vesten<br>
En arme burgery, en op mijn volcx gebed<br>
En dagelix geschrey de bange stad ontzet.

图示 ::first-letter 伪元素

以下 CSS 将使首字下沉跨越约两行:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
 <HEAD>
  <TITLE>Drop cap initial letter</TITLE>
  <STYLE type="text/css">
   P               { font-size: 12pt; line-height: 1.2 }
   P::first-letter { font-size: 200%; font-weight: bold; float: left }
   SPAN            { text-transform: uppercase }
  </STYLE>
 </HEAD>
 <BODY>
  <P><SPAN>The first</SPAN> few words of an article
    in The Economist.</P>
 </BODY>
</HTML>

此示例可能格式化如下:

图示 ::first-letter 和 ::first-line 伪元素的组合效果

虚构标签序列是:

<P>
<SPAN>
<P::first-letter>
T
</P::first-letter>he first
</SPAN>
few words of an article in the Economist.
</P>

请注意,::first-letter 伪元素标签紧贴内容(即首字符),而 ::first-line 伪元素的开始标签插入在块级元素的开始标签之后。

为了实现传统的首字下沉格式,用户代理可以近似字体大小,例如对齐基线。此外,格式化时可以考虑字形轮廓。

7.3. 空白

本节故意留空。(本节之前定义了::selection伪元素。)

7.4. ::before::after 伪元素

::before::after 伪元素可用于描述元素内容之前或之后生成的内容。它们在 CSS 2.1 中进行了说明 [CSS21]

::first-letter::first-line 伪元素应用于包含生成内容的元素时,它们应用于包括生成内容的元素的第一个字母或行。

8. 组合器

8.1. 后代组合器

有时,作者可能希望选择器描述文档树中另一个元素的后代元素(例如,“位于 H1 元素内的 EM 元素”)。后代组合器表达这种关系。后代组合器是分隔两个简单选择器序列的空白符。形式为“A B”的选择器表示元素 B 是某个祖先元素 A 的任意后代。

示例:

例如,考虑以下选择器:

h1 em

它表示 em 元素是 h1 元素的后代。这是对以下片段的正确且有效的部分描述:

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

以下选择器:

div * p

表示 p 元素是 div 元素的孙辈或更远的后代。注意两侧的空白符不是通用选择器的一部分;空白符是一个组合器,表示 div 必须是某个元素的祖先,而该元素必须是 p 的祖先。

以下选择器结合了后代组合器和属性选择器,表示一个元素(1)具有 href 属性,(2)位于 p 内,且 p 本身位于 div 内:

div p *[href]

8.2. 子组合器

子组合器描述了两个元素之间的子关系。子组合器由“尖括号符号”(U+003E,>)字符组成,并分隔两个简单选择器序列。

示例:

以下选择器表示 body 的子元素 p

body > p

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

div ol>li p

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

有关选择元素的第一个子元素的信息,请参见上面关于:first-child伪类的部分。

8.3. 兄弟组合器

有两种不同的兄弟组合器:紧邻兄弟组合器和后续兄弟组合器。在这两种情况下,非元素节点(例如元素之间的文本)在考虑元素的相邻关系时会被忽略。

8.3.1. 紧邻兄弟组合器

紧邻兄弟组合器由“加号”(U+002B,+)字符组成,该字符分隔两个简单选择器序列。由这两个序列表示的元素在文档树中共享相同的父元素,并且第一个序列表示的元素紧邻第二个序列表示的元素之前。

示例:

以下选择器表示紧邻 math 元素之后的 p 元素:

math + p

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

h1.opener + h2

8.3.2. 后续兄弟组合器

后续兄弟组合器由“波浪号”(U+007E,~)字符组成,该字符分隔两个简单选择器序列。由这两个序列表示的元素在文档树中共享相同的父元素,并且第一个序列表示的元素在第二个序列表示的元素之前(不一定是紧邻的)。

示例:

h1 ~ pre

表示一个 pre 元素跟随在 h1 之后。它是以下片段的正确且有效的部分描述:

<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>

9. 计算选择器的特异性

选择器的特异性计算如下:

位于否定伪类中的选择器像其他选择器一样计算,但否定本身不计为伪类。

将三个数字 a-b-c 连接在一起(在一个大基数的数字系统中)得出特异性。

示例:

*               /* a=0 b=0 c=0 -> 特异性 =   0 */
LI              /* a=0 b=0 c=1 -> 特异性 =   1 */
UL LI           /* a=0 b=0 c=2 -> 特异性 =   2 */
UL OL+LI        /* a=0 b=0 c=3 -> 特异性 =   3 */
H1 + *[REL=up]  /* a=0 b=1 c=1 -> 特异性 =  11 */
UL OL LI.red    /* a=0 b=1 c=3 -> 特异性 =  13 */
LI.red.level    /* a=0 b=2 c=1 -> 特异性 =  21 */
#x34y           /* a=1 b=0 c=0 -> 特异性 = 100 */
#s12:not(FOO)   /* a=1 b=0 c=1 -> 特异性 = 101 */

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

注意:HTML style 属性中指定的样式的特异性在 CSS 2.1 中有所描述。[CSS21].

10. 选择器的语法

10.1. 语法

下面的语法定义了选择器的语法。它是全局LL(1)且可以是局部LL(2)的(但请注意,大多数UA不应直接使用它,因为它不表达解析约定)。该生成规则的格式已针对人工阅读进行了优化,并使用了一些超出Yacc的简写符号(参见 [YACC]):

生成规则如下:

selectors_group
  : selector [ COMMA S* selector ]*
  ;

selector
  : simple_selector_sequence [ combinator simple_selector_sequence ]*
  ;

combinator
  /* combinators can be surrounded by whitespace */
  : PLUS S* | GREATER S* | TILDE S* | S+
  ;

simple_selector_sequence
  : [ type_selector | universal ]
    [ HASH | class | attrib | pseudo | negation ]*
  | [ HASH | class | attrib | pseudo | negation ]+
  ;

type_selector
  : [ namespace_prefix ]? element_name
  ;

namespace_prefix
  : [ IDENT | '*' ]? '|'
  ;

element_name
  : IDENT
  ;

universal
  : [ namespace_prefix ]? '*'
  ;

class
  : '.' IDENT
  ;

attrib
  : '[' S* [ namespace_prefix ]? IDENT S*
        [ [ PREFIXMATCH |
            SUFFIXMATCH |
            SUBSTRINGMATCH |
            '=' |
            INCLUDES |
            DASHMATCH ] S* [ IDENT | STRING ] S*
        ]? ']'
  ;

pseudo
  /* '::' starts a pseudo-element, ':' a pseudo-class */
  /* Exceptions: :first-line, :first-letter, :before and :after. */
  /* Note that pseudo-elements are restricted to one per selector and */
  /* occur only in the last simple_selector_sequence. */
  : ':' ':'? [ IDENT | functional_pseudo ]
  ;

functional_pseudo
  : FUNCTION S* expression ')'
  ;

expression
  /* In CSS3, the expressions are identifiers, strings, */
  /* or of the form "an+b" */
  : [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+
  ;

negation
  : NOT S* negation_arg S* ')'
  ;

negation_arg
  : type_selector | universal | HASH | class | attrib | pseudo
  ;

10.2. 词法扫描器

以下是标记生成器,使用Flex(参见 [FLEX])表示法编写。标记生成器是不区分大小写的。

两个 "\377" 表示当前版本的Flex可以处理的最高字符编号(十进制255)。它们应被读取为 "\4177777"(十进制1114111),这是Unicode/ISO-10646中的最高可能码点。[UNICODE]

%option case-insensitive

ident     [-]?{nmstart}{nmchar}*
name      {nmchar}+
nmstart   [_a-z]|{nonascii}|{escape}
nonascii  [^\0-\177]
unicode   \\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?
escape    {unicode}|\\[^\n\r\f0-9a-f]
nmchar    [_a-z0-9-]|{nonascii}|{escape}
num       [0-9]+|[0-9]*\.[0-9]+
string    {string1}|{string2}
string1   \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*\"
string2   \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*\'
invalid   {invalid1}|{invalid2}
invalid1  \"([^\n\r\f\\"]|\\{nl}|{nonascii}|{escape})*
invalid2  \'([^\n\r\f\\']|\\{nl}|{nonascii}|{escape})*
nl        \n|\r\n|\r|\f
w         [ \t\r\n\f]*

D         d|\\0{0,4}(44|64)(\r\n|[ \t\r\n\f])?
E         e|\\0{0,4}(45|65)(\r\n|[ \t\r\n\f])?
N         n|\\0{0,4}(4e|6e)(\r\n|[ \t\r\n\f])?|\\n
O         o|\\0{0,4}(4f|6f)(\r\n|[ \t\r\n\f])?|\\o
T         t|\\0{0,4}(54|74)(\r\n|[ \t\r\n\f])?|\\t
V         v|\\0{0,4}(58|78)(\r\n|[ \t\r\n\f])?|\\v

%%

[ \t\r\n\f]+     return S;

"~="             return INCLUDES;
"|="             return DASHMATCH;
"^="             return PREFIXMATCH;
"$="             return SUFFIXMATCH;
"*="             return SUBSTRINGMATCH;
{ident}          return IDENT;
{string}         return STRING;
{ident}"("       return FUNCTION;
{num}            return NUMBER;
"#"{name}        return HASH;
{w}"+"           return PLUS;
{w}">"           return GREATER;
{w}","           return COMMA;
{w}"~"           return TILDE;
":"{N}{O}{T}"("  return NOT;
@{ident}         return ATKEYWORD;
{invalid}        return INVALID;
{num}%           return PERCENTAGE;
{num}{ident}     return DIMENSION;
"<!--"           return CDO;
"-->"            return CDC;

\/\*[^*]*\*+([^/*][^*]*\*+)*\/                    /* ignore comments */

.                return *yytext;

11. 概要文件

每个使用选择器的规范必须定义它允许和排除的选择器子集,并描述该子集中所有组件的局部含义。

非规范性示例:

选择器概要文件
规范 CSS level 1
接受 类型选择器
类选择器
ID 选择器
:link, :visited 和 :active 伪类
后代组合器
::first-line 和 ::first-letter 伪元素
排除

通用选择器
属性选择器
:hover 和 :focus 伪类
:target 伪类
:lang() 伪类
所有 UI 元素状态伪类
所有结构性伪类
否定伪类
::before 和 ::after 伪元素
子组合器
兄弟组合器

命名空间

额外限制 每个简单选择器序列仅允许一个类选择器


选择器概要文件
规范 CSS level 2
接受 类型选择器
通用选择器
属性存在和值选择器
类选择器
ID 选择器
:link, :visited, :active, :hover, :focus, :lang() 和 :first-child 伪类
后代组合器
子组合器
下一个兄弟组合器
::first-line 和 ::first-letter 伪元素
::before 和 ::after 伪元素
排除

子串匹配属性选择器
:target 伪类
所有 UI 元素状态伪类
除 :first-child 之外的所有结构性伪类
否定伪类
后续兄弟组合器

命名空间

额外限制 允许每个简单选择器序列中多个类选择器(CSS1 限制)

在 CSS 中,选择器表示模式匹配规则,用于确定哪些样式规则适用于文档树中的元素。

以下选择器(CSS level 2)将匹配在章节 1 标题 h1 内设置了 name 属性的所有锚点 a

h1 a[name]

所有附加到此类选择器的 CSS 声明都将应用于与其匹配的元素。

选择器概要文件
规范 STTS 3
接受

类型选择器
通用选择器
属性选择器
类选择器
ID 选择器
所有结构性伪类
所有组合器

命名空间

排除 不接受的伪类
伪元素
额外限制 某些选择器和组合器不允许在 STTS 声明右侧的片段描述中使用。

选择器在 STTS 3 中可用于两种不同的方式:

  1. 与 CSS 选择机制等效的选择机制:附加到给定选择器的声明应用于与该选择器匹配的元素,
  2. 片段描述出现在声明右侧。

12. 一致性与要求

本节仅定义了与当前规范的一致性。

由于特定设备的限制,用户代理无法实现本规范的一部分(例如,非交互式用户代理可能不会实现动态伪类,因为它们在没有交互性的情况下没有意义),这并不意味着不符合规范。

所有重用选择器的规范必须包含概要文件,列出它接受或排除的选择器子集,并描述它对当前规范添加的限制。

无效性是由解析错误引起的,例如未识别的标记或当前解析点不允许的标记。

用户代理必须遵守处理解析错误的规则:

重用选择器的规范必须定义如何处理解析错误。(在 CSS 的情况下,将丢弃使用该选择器的整个规则。)

13. 测试

本规范有一个测试套件,允许用户代理验证其对规范的基本一致性。该测试套件并不声称是详尽无遗的,也不涵盖选择器的所有可能组合情况。

14. 致谢

CSS 工作组感谢多年来对本规范提出意见的所有人。

特别是,工作组想向 Donna McManus、Justin Baker、Joel Sklar 和 Molly Ives Brower 致以特别的谢意,他们对最后的草案进行了最终的编辑审查。工作组还要感谢 Adam Kuehn、Boris Zbarsky、David Perrell、Elliotte Harold、Matthew Raymond、Ruud Steltenpool、Patrick Garies、Anton Prowse 和 W3C 国际化工作组的最后审查意见和友善的言辞。

15. 参考文献

15.1. 规范性参考文献

[CSS21]
Bert Bos 等人。层叠样式表第2级修订版(CSS 2.1)规范。 2011年6月7日。W3C 推荐标准。URL: http://www.w3.org/TR/2011/REC-CSS2-20110607
[CSS3NAMESPACE]
Elika J. Etemad。CSS 命名空间模块第3级。 2011年9月29日。W3C 推荐标准。URL: http://www.w3.org/TR/2014/REC-css-namespaces-3-20140320/
[FLEX]
Flex: 词法扫描生成器。 版本 2.3.7,ISBN 1882114213
[UNICODE]
The Unicode Consortium。Unicode 标准。 2012年。定义自:Unicode 标准,版本 6.2.0(加利福尼亚州山景城:Unicode Consortium,2012年,ISBN 978-1-936213-07-8),并随着新版本的发布不时更新。URL: http://www.unicode.org/standard/versions/enumeratedversions.html
[YACC]
S. C. Johnson。YACC - Yet another compiler compiler。 默里山。1975年。技术报告。

15.2. 参考性文献

[BCP47]
A. Phillips; M. Davis。语言标识标签。 2009年9月。47. BCP。当前由RFC 5646表示。URL: ftp://ftp.rfc-editor.org/in-notes/bcp/bcp47.txt
[CSS1]
Håkon Wium Lie; Bert Bos。层叠样式表(CSS1)第1级规范。 2008年4月11日。W3C 推荐标准。URL: http://www.w3.org/TR/2008/REC-CSS1-20080411
[DOM-LEVEL-3-CORE]
Gavin Nicol 等人。文档对象模型(DOM)第3级核心规范。 2004年4月7日。W3C 推荐标准。URL: http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407
[HTML401]
Dave Raggett; Arnaud Le Hors; Ian Jacobs。HTML 4.01 规范。 1999年12月24日。W3C 推荐标准。URL: http://www.w3.org/TR/1999/REC-html401-19991224
[HTML5]
Ian Hickson 等人。HTML5。 2014年10月28日。W3C 推荐标准。URL: http://www.w3.org/TR/2014/REC-html5-20141028/
[MATHML3]
David Carlisle; Patrick Ion; Robert Miner。数学标记语言(MathML)版本3.0第2版。 2014年4月10日。W3C 推荐标准。URL: http://www.w3.org/TR/2014/REC-MathML3-20140410/
[STTS3]
Daniel Glazman。简单树转换表3。 法国电力公司。1998年11月11日。提交给W3C。URL: http://www.w3.org/TR/NOTE-STTS3
[SVG11]
Erik Dahlström 等人。可缩放矢量图形(SVG)1.1(第二版)。 2011年8月16日。W3C 推荐标准。URL: http://www.w3.org/TR/2011/REC-SVG11-20110816/
[UAX29]
Mark Davis。Unicode 文本分段。 2012年9月12日。Unicode 标准附录#29。URL: http://www.unicode.org/reports/tr29/
[XML-NAMES]
Tim Bray 等人。XML中的命名空间(第三版)。 2009年12月8日。W3C 推荐标准。URL: http://www.w3.org/TR/2009/REC-xml-names-20091208/
[XML10]
C. M. Sperberg-McQueen 等人。可扩展标记语言(XML)1.0(第五版)。 2008年11月26日。W3C 推荐标准。URL: http://www.w3.org/TR/2008/REC-xml-20081126/

15.3. 变更

自上一版推荐标准以来的实质性变更包括: