CSS3选择器规范文档

摘要

选择器是一个模式,在document树中针对元素作匹配,而且这种形式的技术之一,可以用来在一个XML文档中选择节点。为了与HTML和XML配合使用,选择器被优化了,被设计成能够在性能至关重要的代码中使用。

CSS是一种语言,用来描述HTML文档和XML文档在屏幕上,在纸上,在声音里,等地方的呈现。CSS使用选择器,以把样式属性绑定到文档中的元素上。

本文档描述了已经存在于CSS1、CSS2中的选择器,以及将来会在CSS3中引入的选择器中和别的语言中可能需要的选择器。

选择器定义了以下函数:

expression ∗ element → boolean

那是说,给定一个元素和一个选择器,本规范文档定义了这个元素是否匹配该选择器。

这些表达式还可以用来,举个例子,用来选择一个元素集合,或者是来自一个元素集合的一个元素,只要在子树中,跨所有的元素,评估该表达式。STTS(简单树转换表),它是用这个机制转换XML树的一种语言。[STTS3]

本文档的状态

这个章节描述了本文档在它公布时的状态。别的文档可能取代本文档。可以在W3C技术报告索引上找到一个W3C公布以及技术报告的最新版本的列表。

本文档由CSS Working Group工作小组制作,它是一个被提议的建议书

W3C推荐标准是一个成熟的文档,已经被反复检查并且已被证明是可实现的。W3C鼓励每个人实现这个规范文档。有什么意见,可以发送到公共邮件列表www-style@w3.org(请参阅说明书)。在发送邮件时,请把文字“css3-selectors”放在标题中,比如说这样: “[css3-selectors] …summary of comment…”。

本文档已经经过W3C成员的检查,经过软件开发员的检查,还经过了别的W3C小组和利益团体的检查,得到了Director的支持,成为推荐标准。这是一个稳定的文档,可能用作参考材料,或者在别的文档中引用它。W3C在制定本推荐标准中的角色是,着眼于规范,并促进其广泛的频署。它增强了Web的功能以及互操作性。

根据W3C专利政策2004年2月5日版制作了本文档。W3C保留了一个专利公开的公共列表,用以联系小组的可发布成果;那个网页还包括了披露一项专利的指令。拥有专利的实际知识的个人,如果认为包含了Essential Claim(s),必须参照W3C专利政策第六节披露信息。

有一份独立的编译器报告,包含了一些测试套件,显示本规范文档的若干个编译器。

这个文档和以往一样,提出推荐标准版本,除了编辑修改前页,并更新参考资料。

1. 引言

一级选择器和二级选择器,被定义为选择器功能子集,分别定义在CSS1规范文档和CSS2.1规范文档中。

1.1. 依赖性

本规范文档的一些功能是专用于CSS的,或者有些特定的限制,或者规则专用于CSS。在本规范文档中,有一些已经在CSS 2.1中讲解过了。[CSS21]

1.2. 术语

本规范文档中的所有文字都是规范的,除了示例、注意点和一些明确标记为“非规范”的章节。

额外的术语定义在[CSS21]定义章节中。文档示例的源代码和片段,以XML[[XNK10]] 或HTML[[HTML]]句法给出。

1.3. 从CSS2以来的变化

本节并非标准。

在CSS2和CSS3中的选择器的主要区别如下:

2. 选择器

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

一个选择器代表一种结构。这个结构可以用作一个条件(例如,在一个CSS规则中),用来确定文档树中哪些元素匹配一个选择器,或者作为一个XTML片段或XML片段的平实的描述,对应于那些结构。

选择器囊括了简单的元素名到富上下文的代表。

以下表格总结了选择器句法:

模式意义讲解的章节最早定义它的CSS版本
*任何元素普遍选择器2
E一个类型E的元素元素类型选择器1
E[foo]一个带有元素属性“foo”的E元素元素属性选择器2
E[foo="bar"]一个带有元素属性“foo”,且值严格等于“bar”的E元素元素属性选择器2
E[foo~="bar"]一个E元素,它的元素属性“foo”是一个空格隔开的值列表,其中一个值严格等于“bar”元素属性选择器2
E[foo^="bar"]一个E元素,,它的元素属性“foo”严格以字符串“bar”开头元素属性选择器3
E[foo$="bar"]一个E元素,它的元素属性“foo”严格以字符串“bar”结尾元素属性选择器3
E[foo*="bar"]一个E元素,它的元素属性“foo”包含子字符串“bar”元素属性选择器3
E[foo|="en"]一个E元素,它的元素属性“foo”是连字号隔开的列表,该元素属性值以“en”开始(从左侧开始)元素属性选择器2
E:root一个E元素,文档的根节点结构伪类选择器3
E:nth-child(n)一个E元素,它是它的父元素的第n个子元素结构伪类选择器3
E:nth-last-child(n)一个E元素,它是它的父元素的倒数第n个子元素结构伪类选择器3
E:nth-of-type(n)一个E元素,它是同种类型的第n个同辈元素结构伪类选择器3
E:nth-last-of-type(n)一个E元素,它是同种类型的倒数第n个同辈元素结构伪类选择器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 and 2
E:target一个E元素,它是引用URI的目标目标伪类3
E:lang(fr)一个类型E的元素,其语言是“fr”(文档语言指定了如何确定语言):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一个E元素,它的样式类是“warning”(文档语言指定了如何确定样式类)样式类选择器1
E#myid一个E元素,带有id等于“myid”ID选择器1
E:not(s)一个E元素,不匹配简单选择器s否伪类3
E F一个F元素,它是一个E元素的后代元素后代元素组合器1
E > F一个F元素,它是一个E元素的子元素子元素组合器2
E + F一个F元素,它紧挨在一个E元素前面相邻同辈元素组合器2
E ~ F一个F元素,它在一个E元素的前面一般同辈元素组合器3

每个选择器的意思派生自上面这个表,只要把“匹配”插入到“意义”列中每个单元格的内容前面。

3. 大小写敏感性

所有的选择器句法,在ASCII范围内都是大小写不敏感的(亦即,[a-z]和[A-Z]是等同的)。在选择器中,文档语言元素名、元素属性名以及元素属性值的大小写敏感性,取决于文档语言。举个例子,在HTML中,元素名称是大小写不第三的,但是在XML中,它们是大小写敏感的。命名空间前缀的大小写敏感性,定义在[CSS3NAMESPACE]

4. 选择器句法

一个选择器是一个或多个简单选择器序列的连缀,用组合器分隔开几个简单选择器。一个伪元素可以追加到选择器中最后一个序列简单选择器的后面。

一个简单选择器序列简单选择器的连缀,它没有用组合器分隔。它总是用一个元素类型选择器或者一个普遍选择器开始。在序列中不允许别的元素类型选择器或者普遍选择器。

一个简单选择器,是一个元素类型选择器普遍选择器元素属性选择器样式类选择器ID选择器或者伪类选择器

组合器是:空白、“大于符号”(U+003E,>)、“加号”(U+002B,+)、“波浪号”(U+007E,~)。空白可以出现在一个组合器以及简单选择器周围。只有字符“空白”(U+0020)、“换行”(U+000A)、“回车”(U+000D)以及“制表符”(U+000C)可以出现在空白中。别的类似空白的字符,比如说“em空格”(U+2003)和“表义空格”(U+3000),不会成为空白的一部分。

用选择器代表的一个文档树的元素,是选择器的主题。由简单选择器序列构成的选择器代表了满足它的要求的任何元素。把另一个简单选择器序列以及一个组合器置于一个序列前面,强加了额外的匹配约束。因此,一个选择器的主题,总是是同一个选择器的最后一个序列所代表的元素的子集。

一个空选择器,没有包含简单选择器或者伪元素,就是一个无效选择器

选择器中的字符可以用反斜杠转义,要遵守这个转义规则[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 }

警告:在本示例中,该等价物是true,因为所有选择器是有效的选择器。如果这些选择器中的一个是无效的,整个选择器给都会成为无效。这会使三个标题元素的规则都成为无效,而前一种情况只有三个独立标题规则之一成为无效。

无效的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]一个元素类型选择器代表了在文档树中的该元素类型的一个实例。

示例:

下面的选择器代表了document树中的一个h1元素。

h1

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

类型选择器允许一个可选的命名空间成分:一个先前声明过的命名空间前缀,可以前插入到元素名前成,用命名空间分隔符“小竖条”(U+007、|隔开)。(例如,参见[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 }  /* first rule */
 foo|* { color: yellow } /* second rule */
 |h1 { color: red }      /* ...*/
 *|h1 { color: green }
 h1 { color: green }

第一条规则(没有计数@namespace规则)将只匹配“http://www.example.com”命名空间中的h1元素。

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

第三条规则将只匹配不带命名空间的h1元素。

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

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

6.2. 普遍选择器

普遍选择器,写成一个CSS限定名[CSS3NAMESPACE]以及一个梅花星号(* U+002A)作为本地名,代表了任何元素类型的限定名。如果选择器没有指定默认的命名空间,它代表了文档树中任何命名空间(包括没有命名空间)中的任何单个元素。如果已经指定了默认命名空间,请参阅下面的普遍选择器和命名空间

如果用*代表的普遍选择器(亦即,没有命名空间前缀)不是简单选择器序列的唯一成分,或者后面紧跟着一个伪元素,则可以省略*,并潜在地应用普遍选择器。

示例:

  • *[hreflang|=en][hreflang|=en]是等同的,
  • *.warning.warning是等同的,
  • *#myid#myid是等同的。
建议不要省略*,因为它降低了潜在的混乱,比如说,div :first-childdiv:first-child之间的混乱。在这里,div *:first-child更有可读性。

6.2.1. 普遍选择器和命名空间

普遍选择器允许一个可选的命名空间成分。它的用法如下:

ns|*
命名空间ns中的所有元素
*|*
所有元素
|*
不带命名空间的所有元素
*
如果没有指定默认的命名空间,这等同于*|*。否则它等同于ns|*,其中ns是默认命名空间。

一个包含了命名空间前缀的普遍选择器,如果该命名空间前缀还没有declared声明过,则它会是一个无效选择器。

6.3. 元素属性选择器

选择器允许一个元素的元素属性的代表。当一个选择器用作一个用来匹配元素的表单式时,如果某个元素具有一个元素属性,它匹配用某个元素属性选择器代表的元素属性,则该元素属性器必须被视为匹配这个元素。

6.3.1. 元素属性存在选择器和元素属性值选择器

CSS2引入了四个元素属性选择器:

[att]
代表一个带有元素属性attr的元素,无论元素属性的值是什么。
[att=val]
代表一个带有元素属性attr的元素,它的元素属性值严格等于“val”。
[att~=val]
代表一个元素,它的元素属性att的值是一个空格分隔的单词列表,其中一个单词严格等于“val”。如果“val”包含了空白,它不会代表任何东西(因为单词是用空格分隔的。)同样,如果“val”是一个空字符串,它也不会代表任何东西。
[att|=val]
代表了一个带有元素属性att的元素,它的值要么严格等于“val”,要么以“val”开头,后面紧跟着“-”(U+002D)。这主要用来允许语言子码匹配(例如,HTML中的a元素上的元素属性hreflang或者是它的继承者,[BCP47]中讲解了它)。要想进一步了解lang(或xml:lang)语言子码匹配,请参阅:lang伪类

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

示例:

以下的元素属性选择器代表了一个h1元素,它携有元素属性title,无论元素属性的值是什么:

h1[title]

在下面的示例中,选择器代表一个span元素,它的元素属性class严格等于值“example”:

span[class="example"]

多个元素属性选择器可以用来代表一个元素的若干个元素属性,或者同一个元素属性上的若干个条件。在这里,该选择器代表了一个span元素,它的元素属性hello的值严格等于“Cleveland”,而且它的元素属性goodbye的值严格等于“Columbus”:

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

下面的CSS规则演示了“=”和“~=”的区别。举个例子,第一个选择器将匹配一个a元素,带有元素属性rel,其值是“copyright copyleft copyeditor”。第二个选择器只匹配一个a元素,带有元素属性“href”,其值严格等于“http://www.w3.org/”。

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

下面的选择器代表了一个a元素,它的元素属性hreflang严格等于“fr”。

a[hreflang=fr]

下面的选择器代表了一个a元素,它的元素属性hreflang的值以“en”开头,包括“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] 选择器中的元素属性名和元素属性值的大小写敏感性,取决于文档语言。

示例:

以下选择器代表一个HTMLobject,引用一个图像:

object[type^="image/"]

下面的选择器代表了一个HTML锚a,带有一个元素属性href,它的值以“.html”结束。

a[href$=".html"]

以下选择器代表了一个HTML段落文本,带有一个元素属性title,它的值包含了子元素“hello”。

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 }

第一个规则将只匹配,带有“http://www.example.com”命名空间中的元素属性attr的元素,且该元素属性值等于“val”。

第二个规则将只匹配带有元素属性attr的元素,无论元素属性的命名空间是什么(包括没有命名空间)。

最后两条规则是等同的,将只匹配带有元素属性att,而且该元素属性不处于任何命名空间中。

6.3.4. 在DTD上的默认元素属性值

元素属性选择器代表了文档树中的元素属性值。文档树是如何构造的,超出了选择器的范围。在一些文档格式中,元素属性的默认值可以定义在一个DTD中,或者别的地方,但是除非它们出现在文档树中,元素属性选择器才可以选中它们。选择器必须被设计为无论默认值是否包含在文档树中,这个选择器都能够起作用。

举个例子,一个XML用户代理,可能会读取DTD的“外部子集”,但不一定会读取它,但是必须在文档的“内部子集”中搜寻默认元素属性值。(请参见[XML10]以了解这些子集的定义。)取决于用户代理,一个定义在DTD的外部子集中的默认的元素属性值,可能出现在文档树中,也可能文档树中不出现它。

一个识别XML命名空间的用户代理可能会使用它的命名空间的知识去对待元素属性的默认值,就像它们存在在文档中,但是不一定会使用它的这个知识。(举个例子,一个XHTML用户代理不一定要使用它的内置的XHTML DTD的知识。请参见[XML-NAMES]以了解XML 1.0中的命名空间的详情。)

编译器通常会选择忽略额外的子集。这对应于非验证处理器的行为,如XML规范文档所定义。

示例:

设想一个元素EXAMPLE,它带有默认值为"decimal"的元素属性radix。则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配合作用,作者可以使用“点记号法”(也称为“句号”,U+002E,.)作为~=记号法的替代,如果~=记号法代表的是元素属性class。因此,对于HTML,div.valuediv[class~=value]有相同的意义。这个元素属性值必须紧挨在点号后面。

如果用户代理具有命名空间专有的知识,允许它确定哪些元素属性是针对各自命名空间的元素“class”属性,这个用户代理可能在XML文档中使用点(.)记号法应用选择器。命名空间专有知识的一个示例是,规范文档中的散文,针对特定的命名空间。(例如,SVG 1.0 [SVG11]描述了SVG class元素属性,以及用户代理应该如何翻译它,还有类似的MathML 1.01 [MATHML]描述了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有很大的“分类”元素属性的能力,作者可以令人信服地基于元素设计它们自己的“文档语言”,通常与外观没有联系(比如说HTML中的DIVSPAN)并通过元素属性“class”向它们分配样式信息。作者应该避免这种实践,因为文档语言的结构化元素,通常有可识别、已被接受的意义,而作者定义的样式类不一定有这样的意义。
如果一个元素具有多个样式类元素属性,在搜索样式类之前,它们的值必须每个单词之间用空隔连接。然而,因为这时候工作小组还不知道有什么方式可以实现这种情况,所以在这个规范文档不没有明确地规范这种行为。

6.5. ID选择器

文档语言可能包含类型ID声明的元素属性。使ID类型的元素属性特殊的是,在一个格式完好的文档中,没有两个这样的元素属性可以有相同的值,无论携带它们的元素的类型是什么;无论文档语言是什么,一个ID类型元素属性可用于唯一性地识别它的元素。在HTML中,所有的元素ID属性都命名为“id”;XML应用程序可能用不同的方式命名元素ID属性,但是应用了相同的约束。

一种文档语言的ID类型属性允许作者向文档树中的一个元素实例分配一个标识符。一个ID选择器包含了一个井号(U+0023,#)后面紧跟着ID值,它必须是一个CSS标识符。一个ID选择器,代表了一个元素实例,它具有一个标识符,匹配ID选择器中的标识符。

选择器不会指定用户代理如何知道一个元素的ID类型元素属性。用户代理可能,比如说,读取文档的DTD信息,看是否有硬编码的信息,或者询问用户。

示例:

下面的ID选择器代表了一个h1元素,它的ID类型元素属性的值是“chapter1”:

h1#chapter1

下面的ID选择器代表了任何元素,它的ID类型元素属性的值是“chapter1”:

#chapter1

下面的选择器代表任何元素,它的ID类型元素属性具有值“z98y”。

*#z98y
在XML 1.0 [XML10]中,关于哪些元素属性包含元素的ID的信息,包含在一个DTD或架构内。在解析XML的时候,用户代理并不总是会读取DTD,因此可能不知道哪个元素属性是一个元素的ID类型属性(虽然一个用户代理可能会有命名空间知识,允许它确定哪个元素属性是针对这个命名空间的元素ID属性。)如果一个样式表作者知道或者怀疑那个用户代理可能不知道哪个元素属性是一个元素的元素ID属性,它必须使用常规的元素属性选择器来代替它:用[name=p371]代替#p371

如果一个元素具有多个元素ID属性,则几个元素ID属性都被视为ID,可被ID选择器选中。混合使用xml:id、DOM3核心、XML DTD以及命名空间专有的知识,可以产生这种情况。

6.6. 伪类

引入了伪类的概念,以允许基于文档树之外的信息选择元素,或者不能用其它简单选择器表达的信息。

一个伪类总是由一个冒号(:)后面紧跟着伪类名,视情况下有一个值,用圆括号括起来。

在一个选择器中包含的所有简单选择器序列都允许伪类。在简单选择器序列的任何地方都允许伪类,跟在前导的元素类型选择器或普遍选择器(可以省略)后面。伪类名是大小写不敏感的。有些伪类是相互排除的,与此同时,另一些可以同时应用到同一个元素上。伪类可能是动态的,意思是说,当用户与文档互动的时候,一个元素可能得到或失去一个伪类。

6.6.1. 动态伪类

元素可以根据名称、元素属性或内容之外等元素的特征,即,能够从文档树中找到的元素特征,进行分类;但是动态伪类还可以根据此上述特征之外的元素特征对元素进行分类。

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

用户代理通常把未访问过的链接显示得不同于已经访问过的链接。选择器提供了伪类:link:visited来区分它们:

在一段时间以后,用户代理可能会选择把一个已访问链接恢复到未访问的:link状态。

两种状态必须相互排除。

示例:

下面的选择器代表了一个链接,它携带了样式类external,并且已经被访问过了。

a.external:visited
样式表作者可能会滥用:link伪类和:visited伪类,以确定用户已经访问过两个网站,而不需要用户同意。

用户代理在呈现已访问链接和未访问链接的区别的时候,可能会把链接都视为未访问的链接,或者实现别的措施,以保护用户的私隐。

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链接到特定的文档内部特定的元素上,即目标元素。举个例子,这里有一个URI,指向HTML文档中,一个名为section_2的锚。

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

:target伪类可以代表一个目标元素。如果元素的URI没有片段指定符(#),则文档没有目标元素。

示例:

p.note:target

该选择器代表了一个<p class="note">元素,它是引用的URI的目标元素。

CSS示例:

在这里,:target伪类使目标元素变红,并在它前面放置一个图像,如果有目标元素的话:

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

6.6.3. 语言伪类:lang

如果文档语言指定了如何确定一个元素使用了哪种人类语言,就可以基于元素的语言,写出代表一个元素的选择器。举个例子,在HTML [HTML401]中,语言是由元素属性lang和可能来自meta元素的信息,或者来自协议(比如说HTTPudi)的信息共同决定的。XML使用一个称为xml:lang的元素属性,可能还存在别的文档语言指定方法,用来确定语言。

伪类:lang(C)代表了处于语言C中的一个元素。一个元素是否能用:lang()选择器代表,唯一根据元素的语言值(如果必要的话,规范化到BCP 47句法)是否等于标识符C,或者以标识符C开头,后面紧跟着一个“-”(U+002D)。C所匹配的元素属性值是实施为大小写不敏感的。标识符C还没有成为一个有效的语言名。

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

强烈建议表示语言的文档和协议使用来自BCP 47[BCP47]或它的继承者,并在基于XML [XML10]的文档中使用元素属性“xml:lang”。参见"FAQ: 两字母或三字母语言代码"

示例:

下面两个选择器,代表了一个用比列时法语或者德语写的HTML文档。后面两个选择器代表了用比列时法时或德语写的、引括在q内部的任意元素。

html:lang(fr-be)
html:lang(de)
:lang(fr-be) > q
:lang(de) > q

:lang(C)|=操作符的区别是,|=操作符只针对元素上的给定元素属性实施了一个对比,与此同时,:lang(C)伪类使用文档的语义的用户代理知识,以实施这个对比。

在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,例如,display属性和visibility属性对元素上的可用状态和禁用状态不起作用。
6.6.4.2. :checked伪类

用户可以切换单选钮和勾选框元素。当用户选择一些菜单项的时候,这些项会呈“checked”状态。这时,这些元素切换到开启应用:checked伪类。:checked伪类本来是动态的,而且可被用户操作更改,但是因为它同时还基于文档中的语义元素属性的存在与否,它会应用到所有媒体上。举个例子,:checked伪类初始应用到具有HTML元素属性selectedchecked的元素上,如Section 17.2.1 of HTML4所描述,但是用户当然可以切换这样的元素的状态,导致:checked伪类不再应用到这些元素上。

6.6.4.3. :indeterminate伪类
单选钮和勾选框元素,可以被用户切换,但是有时候会处于不确定状态,既没有被勾选中,也没有没被勾选中。这可能因为一个元素的元素属性,或者是因为DOM操纵。
本规范文档的未来版本可能会引入:indeterminate伪类,以应用到这样的元素上。

6.6.5. 结构伪类

选择器引入了结构伪类的概念,以允许基于存在于文档树外、而且不能用别的简单选择器或者组合器代表的信息来制作选区。

在计算元素在它的父元素的子元素列表中的位置时,独立的文本文件和其它非元素节点不计数有内。在计算一个元素在它的父元素的子元素列表中的位置时,索引数字从1开始。

:nth-childnth-last-childnth-of-typenth-last-of-typefirst-childlast-childfirst-of-typelast-of-typeonly-childonly-of-type可以匹配没有父元素的元素,还可以用来选择一个有序列列表树的根节点。例如,:root:nth-child(1)匹配和:root相同的元素。

6.6.5.1. :root伪类

:root伪类代表了一个元素,它是文档的根元素。在HTML 4中,这总会是HTML元素。

6.6.5.2. :nth-child()伪类

 :nth-child(an+b)伪类记号法代表了一个元素,在文档树中,它的前面有an+b-1个同辈元素,而且有一个父元素,n是任何正整数或者0。对于大于零的ab的值,这有效地把元素的子元素分割成a个元素的组(最后一组取用剩余元素),并选择每组中的第b项元素。举个例子,这允许选择器在表格中定位每隔一行,并可以用来以4为循环数交替段落文本的颜色。ab的值必须是整数(正数、负数或零)。一个元素的第一个子元素的索引是1。

除此之外,:nth-child()可以取odd或者even作为它的参数。odd的意义等同于2n+1even的意义等同于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部分已经被省略掉了)。如果an没有包括在内,而且b是非负值,b前面的+号也可以省略掉了(在允许的情况下)。这样的话,句法就简化到了:nth-child(b)

示例:

foo:nth-child(0n+5)   /* 代表一个元素foo,它是它的父元素的第5个子元素 */
foo:nth-child(5)      /* 同上 */

如果a=1或者a=-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) /* 同上 */

“(”后面和“)”的前面允许有空白,分隔an以及b的“+”号或“-”号的两侧也允许有空白,如果两者都出现了的话。

带空格的有效示例:

: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都等于0,该伪类在文档树中不代表任何元素。

a的值可以是负的,但是只有an+b(n≥0)的正值,可以代表文档树中的一个元素。

示例:

html|tr:nth-child(-n+6)  /* 代表XHTML表格中的第六行 */
6.6.5.3. :nth-last-child()伪类

:nth-last-child(an+b)伪类记号法代表了一个元素,在文档树中,它后面有an+b-1个同辈元素,并且有一个父元素,n是任何正整数或者0。参见:nth-child()伪类以了解它的参数的句法。它也接受evenodd值作为参数。

示例:

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是任何正整数或者0。参见:nth-child()伪类以了解它的参数的句法。它也接受evenodd值作为参数。

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是任何正整数或者0。参见:nth-child()伪类以了解它的参数的句法。它也接受evenodd值作为参数。

示例:

要想代表一个XHML 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元素的第一个子元素。

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伪类代表了一个元素,它是别的元素的最后一个子元素。

示例:

下面的选择器代表了一个列表项目li,它是一个有序列表ol的最后子元素。

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元素的有效描述,但是不是第三个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伪类代表了一个元素,它是它的父元素的子元素列表中同类型元素的最后一个同辈元素。

示例:

下面的选择器代表了一个表格行中的最后一个数据单元格td

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

代表一个元素,它有一个父元素,而且它的父元素没有别的子元素。和:first-child:last-child或者:nth-child(1):nth-last-child(1)相同,但是具有较低的专一性。

6.6.5.11. :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(*|*),它不代表任何元素,或者for:not(bar),它等同于foo,但是有更高的专一性。

7. 伪元素

伪元素创超出了用文档语言指定的建抽象的文档树。举个例子,方术语言不会提供访问元素内容的首字母或首行的机制。伪元素允许作者引用别的难以访问的信息。伪元素可能给作作者提供一种方法以引用不存在于源文档中的内容。(例如,::before伪元素和::after伪元素可以访问生成的内容)。

一个伪元素可以由两个冒号(::)后面跟着伪元素的名构成。

当前文档引入::记号法,是为了建立伪类和伪元素之间的区别。为了与已有的样式表兼容,用户代理必须接受以前在CSS Level1和CSS Level 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. First formatted line definition in 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...不能包含任何字母(为HTML4中的br分配了默认样式。)单词"First"没有在第一个格式化行内。

用户代理必须表现得好像::first-line伪元素的虚构的开始标签嵌套在最内层的封闭的块级元素内部。(因为CSS1和CSS2在这种情况下是沉默的,作者不应依赖于这种行为。)举个例子,虚构的标签序列针对

<DIV>
  <P>First paragraph</P>
  <P>Second paragraph</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’、‘vertical-align’、‘text-transform’、‘line-height’。用户代理还可以应用别的元素属性。

在CSS继承中,出现在首行的一个子元素的部分只会继承应用到::first-line伪元素上的属性。对于大多数其它属性,继承来自首先伪元素的非伪元素父元素。(子元素的不出现在首行的部分总是继承那个子元素的父元素的样式。)

7.2. ::first-letter伪元素

::first-letter伪类代表一个元素的首字母,如果它行内前面没有任何内容(比如说图片或内联全格)。::first-letter伪元素可以用于“首字大写”以及“首字下沉”,它们都是常见的排牌效果。

标点符号(亦即,定义在Unicode中的标点符号类的字符"open" (Ps)、"close" (Pe)、"initial" (Pi)、"final" (Pf) 和"other" (Po)),处于第一个字母的前面或后面,必须包括在内。[UNICODE]

第一个字母应该包含前面的引号

如果第一个字母实际上是一个数字,例如,是“"67 million dollars is a lot of money.”中的“6”,也会应用::first-letter

在有些情况下,::first-letter伪元素在一行中会包含不止一个非标点字符。举个例子,组合字符必须和它们的基字符在一起。另外,有些语言可能有关于如何对待某些字母组合的特殊的规则。::first-letter的用户代理定义必须至少包含UAX29定义的默认字形群集,可能适当包含更多字形。举个例子,在德语中,如果字母组合"ij"出现在一个元素的开头,则两个字母都会被视为 ::first-letter伪元素的内容。[UAX29]

如果形成::first-letter的字母不在同一个元素中,比如说<p>'<em>T...中的字母T,用户代理可能根据元素中的一个创建一个::first-letter伪元素,或者根据两个元素创建该伪元素,或者不创建伪元素。

类似地,如果块的首字母不在行的开始处(举个例子,因为双向重排序),则用户代理不需要创建这个伪类。

示例:

下面的CSS和HTML示例演示了如何重叠可能影响到的伪元素。每个<p>元素的首字母具有字体尺寸“font-size:24pt”。第一个格式化行的剩余部分将是“color:blue”,与此同时,段落文本的剩余部分将是“color: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也没有匹配任何东西(假定是HTML4中br的默认样式。)特别是,它不会匹配“First”中的字母“F”。

7.2.1. CSS中的应用程序

在CSS中,::first-letter伪元素应用到类似块的肉器,比如说block元素、list-item元素、table-cell元素、table-caption元素和inline-block元素。注意:本规范文档的未来版本可能会允许在更多display类型上允许这个伪元素。

::first-letter可以与各种元包含文本或者在相同的流中有后代元素包含文本的元素配合使用。用户代理必须表现得仿佛::first-letter伪元素的虚构元素开始标签就在元素的第一段文本前面,甚至哪怕第一段文本是在一个后代元素中。

示例:

针对该HTML片段的虚构的标签序列:

<div>
<p>The first text.

就是:

<div>
<p><div::first-letter><p::first-letter>T</...></...>he first text.

在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中,一个::first-line伪元素如果它的CSS属性‘float’的值是‘none’,它就类似于一个内联级别元素,否则,就类似于一个浮动元素。以下属性应用到::first-letter伪元素上:字体属性、‘text-decoration’、‘text-transform’、‘letter-spacing’、‘word-spacing’(在适当的时候)、‘line-height’、‘float’、‘vertical-align’(只有如果CSS属性‘float’的值是‘none’)、margin属性、padding属性、border属性、color属性、background属性。用户代理也会应用别的元素属性。要想允许用户代理呈现一个正确的首字下层或者首字大写排版效果,用户代理可能基于字母的形状选择一个line-height、width和height,不同于常规元素。

示例:

CSS和HTML示例显示了呈现一个首字大写的可能性。注意,::first-letter伪元素所继承的‘line-height’是1.1,但是在这个示例中,用户代理已经分别计算了首字母的高度,因此它不会导致前两行之间不必要的空间。还要注意首字母的虚构的开始标签是在span内部,因此首字母的font-weight是normal,不是bold,就像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. 空白

这一章节故意留空。(这一章节先前定义了一个::section伪元素。)

7.4. ::before伪元素和::after伪元素

::before选择器和::after选择器可以用来描述在元素的内容前面或后面生成的元素。CSS 2.1中对它们作了解释 [CSS21]

::first-letter伪元素和::first-line伪元素应用到一个具有有::before伪元素或::after伪元素生成的内容的元素上,它们应用到的元素的首字母或首行会包含这些生成的内容。

8. 组合器

8.1. 后代元素组合器

此时,作者可能想用选择器描述一个元素,它是文档树中另一个元素的后代元素(例如,一个EM元素包含在一个H1元素内部)。后代组合器表达了这样的一种关系。一个后代组合器是一个空白,它分隔了简单选择器的两个序列。一个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元素内部,它本身是在一个div元素内部:

div p *[href]

8.2. 子元素组合器

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

示例:

以下选择器代表了一个p元素,它是body的子元素:

body > p

以下示例组合了一个后代元素组合器和一个子元素组合器:

div ol>li p

它代表了一个p元素,是一个li元素的后代元素;li元素必须是一个ol元素的子元素;ol元素必须是一个div元素的后代元素。注意,包围“>”组合器的可有可无的空白,已经被忽略掉了。

对于选中的元素的第一个子元素上的信息,请参阅上面的:first-child伪类章节。

8.3. 同辈元素组合器

有两个不同的同辈元素组合器:相邻同辈元素组合器和一般同辈元素组合器。在两种情况中,当考虑元素的相邻性时,非元素节点(例如,元素之间的文本)会被忽略掉。

8.3.1. 相邻同辈元素组合器

相邻同辈元素组合器由“加号”(U+002B)字符分隔两个简单选择器序列构成。两个序列所代表的元素,在文档树中共享了同一个父元素,而且第一个序列所代表的元素必须紧挨在第二个序列所代表的元素的前面。

示例:

下面的选择器代表了一个p元素,它后面紧跟着一个math元素:

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 -> specificity =   0 */
LI              /* a=0 b=0 c=1 -> specificity =   1 */
UL LI           /* a=0 b=0 c=2 -> specificity =   2 */
UL OL+LI        /* a=0 b=0 c=3 -> specificity =   3 */
H1 + *[REL=up]  /* a=0 b=1 c=1 -> specificity =  11 */
UL OL LI.red    /* a=0 b=1 c=3 -> specificity =  13 */
LI.red.level    /* a=0 b=2 c=1 -> specificity =  21 */
#x34y           /* a=1 b=0 c=0 -> specificity = 100 */
#s12:not(FOO)   /* a=1 b=0 c=1 -> specificity = 101 */
相同的单一选择器允许重复出现,并且增加了专一性。
样式的专一性指定在HTML元素属性style中。[CSS21].

10. 选择器的语法

10.1. 语法

下面的句法定义了选择器的语法。它是全局的LL(1),也可能是局部的LL(2)(但是注意大多数用户代理不会直接使用它,因为它没有表达解析转换)。优化了产品的格式以用于人类消费,而且还使用了一些超过了Yacc的简写法(参见[YACC]):

产品是:

selectors_group
  : selector [ COMMA S* selector ]*
  ;

selector
  : simple_selector_sequence [ combinator simple_selector_sequence ]*
  ;

combinator
  /* 组合器两边可以有空白 */
  : 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
  /* '::'开始了一个伪元素,而':'开始了一个伪类 */
  /* 例外::first-line、:first-letter、:before和:after */
  /* 注意,伪元素被限于每个选择器最多一个伪元素,而且 */
  /* 只出现在最后一个简单选择器序列中 */
  : ':' ':'? [ IDENT | functional_pseudo ]
  ;

functional_pseudo
  : FUNCTION S* expression ')'
  ;

expression
  /* 在CSS3中,这个表达式是标识符、字符串 */
  /* 或者“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;

\/\*[^*]*\*+([^/*][^*]*\*+)*\/                    /* 忽略注释 */

.                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)将匹配设置在标题h1内部的所有带有元素属性name的锚:

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; et al. Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification. 07 June 2011. W3C Recommendation. URL: http://www.w3.org/TR/2011/REC-CSS2-20110607/
[CSS3NAMESPACE]
Elika J. Etemad; Anne van Kesteren. CSS Namespaces Module. 29 September 2011. W3C Recommendation. URL: http://www.w3.org/TR/2011/REC-css3-namespace-20110929/
[FLEX]
Flex: The Lexical Scanner Generator. Version 2.3.7, ISBN 1882114213
[UNICODE]
The Unicode Consortium. The Unicode Standard, Version 6.0.0, (Mountain View, CA: The Unicode Consortium, 2011. ISBN 978-1-936213-01-6) and as updated from time to time by the publication of new versions. (See http://www.unicode.org/unicode/standard/versions/ for the latest version and additional information on versions of the standard and of the Unicode Character Database).
Available at http://www.unicode.org/versions/Unicode6.0.0/
[YACC]
S. C. Johnson. YACC - Yet another compiler compiler. Murray Hill. 1975. Technical Report.

15.2. 其它参考资料

[BCP47]
A. Phillips; M. DavisTags for Identifying Languages and Matching of Language Tags. September 2009. Internet Best Current Practice 47. URL: http://www.rfc-editor.org/rfc/bcp/bcp47.txt
[CSS1]
Håkon Wium Lie; Bert Bos. Cascading Style Sheets (CSS1) Level 1 Specification. 11 April 2008. W3C Recommendation. URL: http://www.w3.org/TR/2008/REC-CSS1-20080411
[DOM-LEVEL-3-CORE]
Gavin Nicol; et al. Document Object Model (DOM) Level 3 Core Specification. 7 April 2004. W3C Recommendation. URL: http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407
[HTML401]
David Raggett; Ian Jacobs; Arnaud Le Hors. HTML 4.01 Specification. 24 December 1999. W3C Recommendation. URL: http://www.w3.org/TR/1999/REC-html401-19991224
[MATHML]
Patrick Ion; Robert Miner. Mathematical Markup Language (MathML) 1.01 Specification. 7 July 1999. W3C Recommendation. URL: http://www.w3.org/1999/07/REC-MathML-19990707
[STTS3]
Daniel Glazman. Simple Tree Transformation Sheets 3. Electricité de France. 11 November 1998. Submission to the W3C. URL: http://www.w3.org/TR/NOTE-STTS3
[SVG11]
Erik Dahlström et. al. Scalable Vector Graphics (SVG) 1.1 Specification. 16 August 2011. W3C Recommendation. URL: http://www.w3.org/TR/2011/REC-SVG11-20110816/
[UAX29]
Mark Davis. Text Boundaries. 25 March 2005. Unicode Standard Annex #29. URL: http://www.unicode.org/unicode/reports/tr29/tr29-9.html
[XML-NAMES]
Tim Bray; et al. Namespaces in XML 1.0 (Third Edition). 6 August 2009. W3C Proposed Edited Recommendation. URL: http://www.w3.org/TR/2009/PER-xml-names-20090806
[XML10]
C. M. Sperberg-McQueen; et al. Extensible Markup Language (XML) 1.0 (Fifth Edition). 10 February 1998. W3C Proposed Edited Recommendation. Revised 5 February 2008 URL: http://www.w3.org/TR/2008/PER-xml-20080205