5 选择器

内容

注意:本规范的若干章节已被其他规范更新。请参阅最新 CSS Snapshot 中的 “层叠样式表 (CSS) — 官方定义”,其中列出了规范以及它们取代的章节。

CSS 工作组也在开发 CSS 2 级修订版 2(CSS 2.2)

5.1 模式匹配

在 CSS 中,模式匹配规则决定哪些样式规则适用于文档树中的元素。这些模式,称为选择器,可能从简单的元素名称到丰富的上下文模式不等。如果某个元素满足模式中的所有条件,则选择器匹配该元素。

选择器中对文档语言元素名称的大小写敏感性取决于文档语言。例如,在 HTML 中,元素名称不区分大小写,而在 XML 中则区分大小写。

下表概括了 CSS 2.1 选择器语法

Pattern含义章节说明
*匹配任何元素。通配选择器
E匹配任何 E 元素(即类型为 E 的元素)。类型选择器
E F匹配任何作为 E 元素后代的 F 元素。后代选择器
E > F匹配任何作为 E 元素子元素的 F 元素。子元素选择器
E:first-child当 E 是其父元素的第一个子元素时匹配 E 元素。:first-child 伪类
E:link
E:visited
匹配元素 E,当其是超链接的源锚点且目标尚未访问(:link)或已访问(:visited)时。链接伪类
E:active
E:hover
E:focus
在特定用户操作期间匹配 E。动态伪类
E:lang(c)如果元素 E 使用(人类)语言 c(文档语言规定了语言的确定方式),则匹配该元素。:lang() 伪类
E + F匹配任何紧随兄弟元素 E 之后的 F 元素。相邻选择器
E[foo]匹配任何设置了“foo”属性(不论属性值为何)的 E 元素。属性选择器
E[foo="warning"]匹配其“foo”属性值恰好等于“warning”的任何 E 元素。属性选择器
E[foo~="warning"]匹配任何其 “foo” 属性值为以空格分隔的列表,且其中恰好有一个值等于 “warning” 的 E 元素。属性选择器
E[lang|="en"]匹配任何其 “lang” 属性值为以连字符分隔的列表且从左起以 “en” 开头的 E 元素。属性选择器
DIV.warning语言特定。(在 HTML 中,与 DIV[class~="warning"] 相同。)类选择器
E#myid匹配任何 ID 等于 “myid” 的 E 元素。ID 选择器

5.2 选择器语法

一个 简单选择器 要么是 类型选择器,要么是 通配选择器,后面紧跟零个或多个 属性选择器ID 选择器伪类,顺序任意。如果其所有组成部分都匹配,则该简单选择器匹配。

注意:这里在 CSS 2.1 中使用的术语与 CSS3 中的用法不同。例如,“简单选择器”在 CSS3 中指的是选择器的更小部分。参见 CSS3 选择器模块 [CSS3SEL]

A 选择器 是由一个或多个简单选择器通过组合符连接形成的链。组合符包括:空白、">" 和 "+"。空白可以出现在组合符两侧的简单选择器之间。

文档树中匹配选择器的元素称为 主体。仅由单个简单选择器组成的选择器匹配满足其要求的任何元素。向链的开头添加一个简单选择器和组合符会施加额外的匹配约束,因此选择器的主体始终是最后一个简单选择器匹配元素的子集。

可以在链的最后一个简单选择器后附加一个 伪元素,在这种情况下,样式信息适用于每个主体的子部分。

5.2.1 分组

When several selectors share the same declarations, they may be grouped into a comma-separated list.

示例

在本例中,我们将三个具有相同声明的规则压缩为一个。因此,

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

等同于

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

CSS 还提供了其他“简写”机制,包括 多个声明简写属性

5.3 通配选择器

The 通配选择器,写作“*”,匹配任何元素类型的名称。它匹配文档树中的任何单个元素。

如果通配选择器不是 简单选择器 的唯一组成部分,则可以省略“*”。例如

5.4 类型选择器

A 类型选择器匹配文档语言元素类型的名称。类型选择器匹配文档树中该元素类型的每个实例。

示例

以下规则匹配文档树中所有 H1 元素

h1 { font-family: sans-serif }

5.5 后代选择器

有时,作者可能希望选择器匹配文档树中另一个元素的后代(例如,“匹配被 H1 元素包含的 EM 元素”)。后代选择器在模式中表达这种关系。后代选择器由两个或更多选择器通过空白分隔组成。形如 “A B” 的后代选择器在元素 B 是某个祖先元素 A 的任意后代时匹配。

示例

例如,考虑以下规则:

h1 { color: red }
em { color: red }

虽然这些规则的意图是通过改变颜色来强调文本,但在如下情况下该效果会丢失:

<H1>This headline is <EM>very</EM> important</H1>

We address this case by supplementing the previous rules with a rule that sets the text color to blue whenever an EM occurs anywhere within an H1

h1 { color: red }
em { color: red }
h1 em { color: blue }

The third rule will match the EM in the following fragment

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

5.6 子代选择器

A 子代选择器在元素是某个元素的子元素时匹配。子代选择器由两个或更多选择器通过 “>” 分隔。

示例

The following rule sets the style of all P elements that are children of BODY

body > P { line-height: 1.3 }

示例

以下示例结合了后代选择器和子代选择器

div ol>li p

它匹配一个 P 元素,该元素是 LI 的后代;LI 元素必须是 OL 元素的子元素;OL 元素必须是 DIV 的后代。注意,“>” 组合符两侧的可选空白已被省略。

有关选择元素的第一个子元素的信息,请参见下面的 :first-child 伪类章节。

5.7 相邻兄弟选择器

相邻兄弟选择器的语法为:E1 + E2,其中 E2 为选择器的主体。如果 E1 与 E2 在文档树中共享同一父节点且 E1 紧接在 E2 之前(忽略非元素节点,如文本节点和注释),则匹配。

示例

因此,下面的规则表示:当 P 元素紧跟在 MATH 元素后面时,不应进行缩进。

math + p { text-indent: 0 } 

The next example reduces the vertical space separating an H1 and an H2 that immediately follows it

h1 + h2 { margin-top: -5mm }   

示例

以下规则类似于前面的示例,只是添加了一个类选择器。因此,仅当 H1 具有 class="opener" 时才会进行特殊格式化。

h1.opener + h2 { margin-top: -5mm }   

5.8 属性选择器

CSS 2.1 允许作者指定匹配在源文档中定义了特定属性的元素的规则。

5.8.1 匹配属性及属性值

属性选择器可以通过四种方式匹配

[att]
Match when the element sets the "att" attribute, whatever the value of the attribute.
[att=val]
Match when the element's "att" attribute value is exactly "val".
[att~=val]
表示具有 att 属性且其值为以空格分隔的单词列表,其中恰好有一个单词等于 “val”。如果 “val” 包含空格,则永远不会匹配(因为单词是用空格分隔的)。如果 “val” 为空字符串,也永远不会匹配。
[att|=val]
表示具有 att 属性且其值要么完全等于 “val”,要么以 “val” 紧跟连字符 “-”(U+002D) 开头。这主要用于允许 语言子码匹配(例如 HTML 中 a 元素的 hreflang 属性),如 BCP 47 ([BCP47]) 或其后继规范。对于 lang(或 xml:lang)语言子码匹配,请参见 :lang 伪类

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

示例

For example, the following attribute selector matches all H1 elements that specify the "title" attribute, whatever its value

h1[title] { color: blue; }

示例

In the following example, the selector matches all SPAN elements whose "class" attribute has exactly the value "example"

span[class=example] { color: blue; }

可以使用多个属性选择器来引用元素的多个属性,甚至多次引用同一属性。

示例

Here, the selector matches all SPAN elements whose "hello" attribute has exactly the value "Cleveland" and whose "goodbye" attribute has exactly the value "Columbus"

span[hello="Cleveland"][goodbye="Columbus"] { color: blue; }

示例

以下选择器说明了 “=” 与 “~=” 的区别。第一个选择器会匹配例如 “rel” 属性值为 “copyright copyleft copyeditor”。第二个选择器仅在 “href” 属性值为 “https://w3org.cn/” 时匹配。

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

示例

下面的规则隐藏所有 “lang” 属性值为 “fr” 的元素(即语言为法语的元素)。

*[lang=fr] { display : none }

示例

以下规则将匹配以 “en” 开头的 “lang” 属性值,包括 “en”、 “en-US” 和 “en-cockney”。

*[lang|="en"] { color : red }

示例

类似地,下面的听觉样式表规则可使脚本在不同角色下以不同的声音朗读。

DIALOGUE[character=romeo] 
     { voice-family: "Laurence Olivier", charles, male }
      
DIALOGUE[character=juliet]  
     { voice-family: "Vivien Leigh", victoria, female }

5.8.2 DTD 中的默认属性值

匹配发生在文档树中的属性值上。默认属性值可以在DTD或其他位置定义,但并不总是能被属性选择器选中。样式表应设计为即使文档树中未包含默认值也能工作。

更精确地说,UA 可以(但不必)读取 DTD 的“外部子集”,但必须在文档的“内部子集”中查找默认属性值。(参见 [XML10] 中对这些子集的定义。)根据 UA 的不同,DTD 外部子集定义的默认属性值可能会出现在文档树中,也可能不会。

能够识别 XML 命名空间的 UA [XMLNAMESPACES]可能会(但并非必需)使用对该命名空间的了解,将默认属性值视为已出现在文档中。(例如,XHTML UA 并不必须使用其对 XHTML DTD 的内建了解。)

请注意,通常实现会选择忽略外部子集。

示例

示例

例如,考虑一个元素 EXAMPLE,具有默认值为 “decimal” 的属性 “notation”。DTD 片段可能是

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

如果样式表包含规则

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

第一个规则可能无法匹配其 “notation” 属性由默认值设置的元素,即未显式设置的情况。要捕获所有情况,必须删除对默认值的属性选择器。

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

这里,因为选择器 EXAMPLE[notation=octal]特异性高于仅类型选择器,所以第二条规则的样式声明将在属性值为 “octal” 的元素上覆盖第一条规则。必须确保所有仅应在默认情况下应用的属性声明在非默认情况下的样式规则中被覆盖。

5.8.3 类选择器

在 HTML 中,作者可以使用点号(.)符号作为表示 class 属性的替代写法,而不是使用 ~= 记法。因此,对于 HTML,div.valuediv[class~=value] 含义相同。属性值必须紧跟在点号后。若 UA 在 XML 文档中拥有特定命名空间的知识,能够判断哪个属性是对应命名空间的 “class” 属性,则也可以在 XML 中使用点号(.)记法。此类命名空间特定知识的示例包括特定命名空间规范的正文(例如 SVG 1.1 [SVG11] 描述了 SVG “class” 属性以及 UA 应如何解释,MathML 3.0 [MATH30] 同样描述了 MathML “class” 属性)。

示例

For example, we can assign style information to all elements with class~="pastoral" as follows

*.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” 值的子集,每个值必须前置一个 “.”。

示例

例如,下面的规则匹配任何 “class” 属性值列表中同时包含 “pastoral” 与 “marine” 的 P 元素。

 
p.marine.pastoral { color: green }

该规则匹配 class="pastoral blue aqua marine",但不匹配 class="pastoral blue"

注意。 CSS 对 “class” 属性赋予了极大的权力,以至于作者可能会基于几乎没有呈现关联的元素(如 HTML 中的 DIV 与 SPAN)并通过 “class” 属性分配样式信息,从而设计出自己的“文档语言”。作者应避免这种做法,因为文档语言的结构元素通常已有公认且接受的含义,而作者自定义的类可能没有。

注意: 如果元素具有多个 class 属性,则在搜索类时必须将它们的值用空格连接在一起。到目前为止工作组并未知晓任何实现会出现此情况,因此此行为在本规范中明确为非规范性。

5.9 ID 选择器

文档语言可能包含声明为 ID 类型的属性。ID 类型属性的特殊之处在于没有两个此类属性可以具有相同的值;无论文档语言如何,ID 属性都可唯一标识其元素。在 HTML 中,所有 ID 属性均命名为 “id”;XML 应用程序可能使用不同的名称,但同样的限制适用。

文档语言的 ID 属性允许作者为文档树中的某个元素实例分配标识符。CSS ID 选择器根据其标识符匹配元素实例。CSS ID 选择器包含一个紧跟在“#”后的 ID 值,该值必须是标识符。

注意,CSS 并未规定 UA 如何获知元素的 ID 属性。例如,UA 可以读取文档的 DTD、将信息硬编码,或询问用户。

示例

以下 ID 选择器匹配 ID 属性值为 “chapter1” 的 H1 元素。

h1#chapter1 { text-align: center }

在以下示例中,样式规则匹配 ID 值为 “z98y” 的元素。因此,该规则将匹配 P 元素。

<HEAD>
  <TITLE>Match P</TITLE>
  <STYLE type="text/css">
    *#z98y { letter-spacing: 0.3em }
  </STYLE>
</HEAD>
<BODY>
   <P id=z98y>Wide text</P>
</BODY>

然而,在下一个示例中,样式规则仅匹配 ID 值为 “z98y” 的 H1 元素。该规则不会匹配此示例中的 P 元素。

<HEAD>
  <TITLE>Match H1 only</TITLE>
  <STYLE type="text/css">
    H1#z98y { letter-spacing: 0.5em }
  </STYLE>
</HEAD>
<BODY>
   <P id=z98y>Wide text</P>
</BODY>

ID 选择器的特异性高于属性选择器。例如,在 HTML 中,选择器 #p123层叠 中比 [id=p123] 更具体。

注意。 在 XML 1.0 [XML10] 中,关于哪个属性包含元素 ID 的信息包含在 DTD 中。解析 XML 时,UA 并不总是读取 DTD,因而可能不知道元素的 ID。如果样式表设计者知道或怀疑会出现这种情况,应使用普通属性选择器,例如 [name=p371] 而非 #p371。然而,普通属性选择器的层叠顺序不同于 ID 选择器,可能需要为声明添加 “!important” 优先级,例如 [name=p371] {color: red ! important}

如果元素具有多个 ID 属性,则这些属性全部必须被视为该元素的 ID,以便 ID 选择器使用。这种情况可能通过 xml:id [XMLID]、DOM3 Core [DOM-LEVEL-3-CORE]、XML DTD [XML10] 和特定命名空间的知识混合使用时可能出现。

5.10 伪元素伪类

在 CSS 2.1 中,样式通常基于元素在文档树中的位置附加到元素上。这一简单模型足以满足许多情况,但某些常见的出版场景可能因文档树结构而无法实现。例如,在 HTML 4(参见 [HTML4])中,没有元素引用段落的第一行,因此没有简单的 CSS 选择器可以引用它。

CSS 引入了 伪元素伪类 的概念,以便基于文档树之外的信息进行格式化。

伪元素和伪类都不出现在文档源代码或文档树中。

伪类可以出现在选择器的任意位置,而伪元素只能附加在选择器的最后一个简单选择器之后。

伪元素和伪类的名称不区分大小写。

某些伪类互斥,而另一些可以同时应用于同一元素。出现冲突规则时,正常的 层叠顺序 决定结果。

5.11 伪类

5.11.1 :first-child 伪类

:first-child 伪类匹配作为某个其他元素的第一个子元素的元素。

示例

In the following example, the selector matches any P element that is the first child of a DIV element. The rule suppresses indentation for the first paragraph of a DIV

div > p:first-child { text-indent: 0 }
This selector would match the P inside the DIV of the following fragment
<P> The last P before the note.
<DIV class="note">
   <P> The first P inside the note.
</DIV>
but would not match the second P in the following fragment
<P> The last P before the note.
<DIV class="note">
   <H2>Note</H2>
   <P> The first P inside the note.
</DIV>

示例

以下规则将字体粗细设为 “bold”,用于任何是某个 P 元素的后代且该 P 元素是其父元素的第一个子元素的 EM 元素。

p:first-child em { font-weight : bold }

请注意,由于匿名框不属于文档树,在计算首子元素时不计入。

For example, the EM in

<P>abc <EM>default</EM> 
is the first child of the P.

以下两个选择器等价。

* > a:first-child   /* A is first child of any element */
a:first-child       /* Same */

5.11.2 链接伪类:link:visited

用户代理通常会以不同方式显示未访问的链接和已访问的链接。CSS 提供伪类 ':link' 和 ':visited' 用于区分它们。

UA 可能在某时将已访问的链接恢复到(未访问的)':link' 状态。

这两种状态是互斥的。

文档语言决定哪些元素是超链接源锚点。例如,在 HTML4 中,链接伪类适用于具有 “href” 属性的 A 元素。因此,以下两个 CSS 2.1 声明具有类似效果。

a:link { color: red }
:link  { color: red }

示例

若以下链接

<A class="external" href="http://out.side/">external link</A>
已被访问,则该规则
a.external:visited { color: blue }
会使其呈现为蓝色。

注意:样式表作者可能滥用 :link 与 :visited 伪类来在未经用户同意的情况下判断用户访问了哪些站点。

因此,UA 可以将所有链接视为未访问链接,或采取其他措施在渲染已访问和未访问链接时保护用户隐私。更多关于隐私处理的信息,请参见 [P3P]

5.11.3 动态伪类: :hover:active:focus

交互式用户代理有时会根据用户操作更改渲染。CSS 为常见情况提供了三个伪类。

一个元素可能同时匹配多个伪类。

CSS 并未定义哪些元素可以处于上述状态,或如何进入和离开这些状态。脚本可能会改变元素是否响应用户事件,不同的设备和 UA 可能有不同的指向或激活元素的方式。

CSS 2.1 未定义处于 ':active' 或 ':hover' 状态的元素的父元素是否也处于相同状态。

用户代理不必因伪类转换而重新排版当前显示的文档。例如,样式表可能指定 :active 链接的 font-size 大于非激活链接的大小,但由于这可能导致读者选择链接时字母位置改变,UA 可以忽略相应的样式规则。

示例

a:link    { color: red }    /* unvisited links */
a:visited { color: blue }   /* visited links   */
a:hover   { color: yellow } /* user hovers     */
a:active  { color: lime }   /* active links    */

请注意,A:hover 必须放在 A:link 与 A:visited 规则之后,否则层叠规则会隐藏 A:hover 规则的color属性。同样,因为 A:active 放在 A:hover 之后,当用户既激活又悬停在 A 元素上时,活动颜色(青柠色)将生效。

示例

一个组合动态伪类的示例

a:focus { background: yellow }
a:focus:hover { background: white }

最后的选择器匹配同时处于伪类 :focus 与 :hover 的 A 元素。

有关焦点轮廓呈现的信息,请参阅 动态焦点轮廓章节。

注意。 在 CSS1 中,:active 伪类与 :link 和 :visited 互斥。现在不再如此。元素可以同时是 :visited 与 :active(或 :link 与 :active),正常的层叠规则决定哪条样式声明生效。

注意。 同时要注意,在 CSS1 中,:active 伪类仅适用于链接。

5.11.4 语言伪类:lang

如果文档语言规定了如何确定元素的自然语言,则可以在 CSS 中编写基于语言匹配元素的选择器。例如,在 HTML [HTML4] 中,语言由 “lang” 属性、META 元素以及可能的协议信息(如 HTTP 头)组合决定。XML 使用名为 xml:lang 的属性,且可能还有其他文档语言特定的方法来确定语言。

:lang(C) 伪类在元素的语言为 C 时匹配。匹配仅依据标识符 C 是否等于或是元素语言值以连字符分隔的子串,类似于 '|=' 操作符的行为。对元素语言值中 ASCII 范围内的字符进行不区分大小写的比较。标识符 C 不必是有效的语言名称。

C 不能为空。

注意:推荐文档和协议使用 BCP 47 [BCP47] 或其后继的代码来指示语言,并在 XML 文档中使用 “xml:lang” 属性 [XML10]。参见 “FAQ:两字母或三字母语言代码”。

示例

以下规则为 HTML 文档设置引号,当文档语言为加拿大法语或德语时。

html:lang(fr-ca) { quotes: '� ' ' �' }
html:lang(de) { quotes: '�' '�' '\2039' '\203A' }
:lang(fr) > Q { quotes: '� ' ' �' }
:lang(de) > Q { quotes: '�' '�' '\2039' '\203A' }

第二对规则实际上根据父元素的语言在 Q 元素上设置'quotes'属性。这是因为引号的选择通常取决于引用所在元素的语言,而不是引用本身:例如,法语片段 “à l'improviste” 插入英文文本中仍使用英文引号。

注意 [lang|=xx] 与 :lang(xx) 的区别。在此 HTML 示例中,仅 BODY 匹配 [lang|=fr](因为它具有 LANG 属性),而 BODY 和 P 都匹配 :lang(fr)(因为它们都使用法语)。

<body lang=fr>
  <p>Je suis Français.</p>
</body>

5.12 伪元素

伪元素在 CSS 中行为如同真实元素,但有以下例外以及在其他位置的说明。

请注意,以下章节未对 ':first-line' 与 ':first-letter' 在所有情况下的精确渲染进行定义。未来的 CSS 级别可能会更精确地定义它们。

5.12.1 :first-line 伪元素

:first-line 伪元素对段落的第一行内容应用特殊样式。例如

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

上述规则的含义是“将每个段落第一行的字母转换为大写”。然而,选择器 “P:first-line” 并不匹配任何真实的 HTML 元素。它匹配一个伪元素,符合规范的用户代理会在每个段落的开头插入该伪元素。

请注意,第一行的长度取决于多种因素,包括页面宽度、字号等。因此,一个普通的 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>

:first-line 伪元素只能附加到块容器元素上。

元素的“首行格式化行”可能出现在同一流中的块级后代内部(即不是定位的也不是浮动的块级后代)。例如,<DIV><P>This line...</P></DIV> 中 DIV 的首行是 P 的首行(假设 P 与 DIV 都是块级)。

表格单元格或 inline-block 的首行不能作为祖先元素的首行格式化行。例如,在 <DIV><P STYLE="display: inline-block">Hello<BR>Goodbye</P> etcetera</DIV> 中,DIV 的首行并不是 “Hello”。

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

UA 应当表现得好像 :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 伪元素类似于内联级元素,但有特定限制。以下属性适用于 :first-line 伪元素:字体属性颜色属性背景属性word-spacingletter-spacingtext-decorationtext-transformline-height。UA 也可能应用其他属性。

5.12.2 :first-letter 伪元素

:first-letter 伪元素必须选取块的第一行的第一个字母,前提是该行没有其他内容(如图像或内联表格)在其前面。:first-letter 伪元素可用于首字母大写首字下沉,这两者是常见的排版效果。如果其float属性为 'none',则该初始字母类似于内联级元素,否则类似于浮动元素。

以下属性适用于 :first-letter 伪元素:字体属性, 'text-decoration', 'text-transform', 'letter-spacing', 'word-spacing'(视情况而定), 'line-height', 'float', 'vertical-align'(仅当 'float' 为 'none' 时), 外边距属性, 内边距属性, 边框属性, 颜色属性, 背景属性。 用户代理也可以应用其他属性。为了让 UA 能够渲染排版上正确的首字母放大(drop cap)或首字母大写,UA 可以根据字母的形状自行选择行高、宽度和高度,这与普通元素不同。预计 CSS3 将引入专门适用于 :first-letter 的属性。

此示例展示了一种可能的首字母大写渲染效果。请注意,继承给 :first-letter 伪元素的 'line-height' 为 1.1,但本例中的 UA 对首字母的高度进行了不同的计算,以避免在前两行之间出现不必要的空白。另外请注意,首字母的虚构开始标签位于 SPAN 内部,因此首字母的字体粗细为 normal,而不是 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.

Image illustrating the :first-letter pseudo-element

以下 CSS 2.1 代码会使首字母(drop cap)跨大约两行显示。

<!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-style: italic;
                    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 伪元素组合效果的图片   [D]

虚构的标签序列为:

<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 伪元素的开始标签则插入在块级元素的开始标签之后。

为了实现传统的首字母放大排版,用户代理可以对字体大小进行近似计算,例如对齐基线。同时,字形轮廓在排版时也可以被考虑进来。

前置或后置于首字母的标点符号(即 Unicode [UNICODE] 中的 “开括号”(Ps)、“闭括号”(Pe)、“首字符”(Pi)、“尾字符”(Pf) 以及 “其他”(Po) 类)应当被纳入计算,例如:

应当将首字母前的引号计入   [D]

如果首字符实际上是数字,':first-letter' 仍然适用,例如 “67 million dollars is a lot of money.” 中的 “6”。

:first-letter 伪元素适用于 块级容器元素

:first-letter 伪元素可用于所有包含文本的此类元素,或其同一流中拥有包含文本后代的元素。即使首文本位于后代节点,UA 也应视同首字母伪元素的虚构开始标签位于元素的首个文本之前。

示例

下面给出一个示例。该 HTML 片段的虚构标签序列为:

<div>
<p>The first text.

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

表格单元格或 inline‑block 的首字母不能成为其祖先元素的首字母。因此,在 <DIV><P STYLE="display: inline-block">Hello<BR>Goodbye</P> etcetera</DIV> 中,DIV 的首字母不是 “H”。实际上,DIV 并没有首字母。

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

如果元素是 列表项('display: list-item'),:first-letter 适用于标记之后主框盒的首字母。对于 'list-style-position: inside' 的列表项,UA 可以忽略 :first-letter。如果元素具有 ':before' 或 ':after' 生成内容,:first-letter 仍然适用于该元素的首字母,包括该生成内容。

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

某些语言对特定字母组合有专门规则。例如在荷兰语中,若词首为 “ij”,则这两个字母都应视为属于 :first-letter 伪元素的一部分。

如果构成首字母的字母不在同一元素中,例如 <p>'<em>T... 中的 “'T”,UA 可以仅从其中一个元素创建 :first-letter 伪元素、从两个元素创建,或根本不创建伪元素。

同理,如果块级元素的首字母(或首字母组合)并未位于行首(例如因双向文本重排),则 UA 可以不创建相应的伪元素。

示例

The following example illustrates how overlapping pseudo-elements may interact. The first letter of each P element will be green with a font size of '24pt'. The rest of the first formatted line will be 'blue' while the rest of the paragraph will be '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>

Note that the :first-letter element is inside the :first-line element. Properties set on :first-line are inherited by :first-letter, but are overridden if the same property is set on :first-letter.

5.12.3 The :before:after 伪元素

':before' 与 ':after' 伪元素可用于在元素内容之前或之后插入生成的内容。它们的用法详见 生成文本 部分。

示例

h1:before {content: counter(chapno, upper-roman) ". "}

当 :first-letter 与 :first-line 伪元素应用于使用 :before 与 :after 生成内容的元素时,它们同样作用于包括生成内容在内的元素的首字母或首行。

示例

p.special:before {content: "Special! "}
p.special:first-letter {color: #ffd800}

这将把 “Special!” 中的 “S” 渲染为金色。