5 选择器

目录

5.1 模式匹配

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

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

下表总结了 CSS 2.2 选择器语法:

模式 含义 描述的章节
* 匹配任何元素。 通用选择器
E 匹配任何 E 元素(即类型为 E 的元素)。 类型选择器
E F 匹配任何 F 元素,该元素是 E 元素的后代。 后代选择器
E > F 匹配任何 F 元素,该元素是 E 元素的子元素。 子选择器
E:first-child 当 E 是其父元素的第一个子元素时,匹配元素 E。 :first-child 伪类
E:link
E:visited
如果 E 是超链接的源锚点,且目标尚未访问(:link)或已访问(:visited),则匹配元素 E。 链接伪类
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.2 中使用的术语与 CSS3 中的不同。例如,“简单选择器”在 CSS3 中指的是比 CSS 2.2 中更小的选择器部分。参见 CSS3 选择器模块 [CSS3SEL]

选择器是一串由组合符分隔的一个或多个简单选择器。组合符包括:空白、“>” 和 “+”。组合符与其周围的简单选择器之间可以出现空白。

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

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

5.2.1 分组

当多个选择器共享相同的声明时,它们可以分组为一个用逗号分隔的列表。

示例:

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

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 通用选择器

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

如果通用选择器不是简单选择器的唯一组件,则 "*" 可以省略。例如:

5.4 类型选择器

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

示例:

以下规则匹配文档树中的所有 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>

我们通过补充一条规则来解决这种情况,该规则规定只要 EM 出现在 H1 中,文本颜色就会变为蓝色:

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

第三条规则将匹配以下片段中的 EM:

<H1>This <SPAN class="myclass">headline 
is <EM>very</EM> important</SPAN></H1>

示例:

以下选择器:

div * p 

匹配作为 DIV 元素的孙辈或更后代的 P 元素。请注意,"*" 两侧的空白不是通用选择器的一部分;空白是一个组合符,表示 DIV 必须是某个元素的祖先,并且该元素必须是 P 的祖先。

示例:

以下规则中的选择器结合了后代选择器和属性选择器,匹配以下元素:(1)设置了 "href" 属性且(2)位于 P 内,而 P 本身位于 DIV 内:

div p *[href]

5.6 子选择器

子选择器用于匹配某个元素的子元素。子选择器由两个或多个选择器组成,并用 ">" 分隔。

示例:

以下规则设置了所有作为 BODY 子元素的 P 元素的样式:

body > P { line-height: 1.3 }

示例:

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

div ol>li p

它匹配作为 LI 后代的 P 元素;LI 元素必须是 OL 元素的子元素;OL 元素必须是 DIV 的后代。注意 ">" 组合符周围的可选空白已被省略。

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

5.7 相邻兄弟选择器

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

示例:

因此,以下规则规定,当 P 元素紧跟在 MATH 元素之后时,不应缩进:

math + p { text-indent: 0 } 

下一个示例减少了紧跟在 H1 之后的 H2 之间的垂直空间:

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

示例:

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

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

5.8 属性选择器

CSS 2.2 允许作者指定规则,以匹配在源文档中定义了某些属性的元素。

5.8.1 匹配属性和属性值

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

[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 伪类

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

示例:

例如,以下属性选择器匹配所有指定了 "title" 属性的 H1 元素,无论其值是什么:

h1[title] { color: blue; }

示例:

在以下示例中,选择器匹配所有 "class" 属性值正好为 "example" 的 SPAN 元素:

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

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

示例:

此处,选择器匹配所有 "hello" 属性值正好为 "Cleveland" 且 "goodbye" 属性值正好为 "Columbus" 的 SPAN 元素:

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

示例:

以下选择器说明了 "=" 和 "~=" 之间的区别。第一个选择器将匹配 "rel" 属性值为 "copyright copyleft copyeditor" 的元素。第二个选择器仅在 "href" 属性的值为 "http://www.w3.org/" 时匹配。

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

示例:

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

*[lang=fr] { display : none }

示例:

以下规则将匹配 "lang" 属性值以 "en" 开头的元素,包括 "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 的“外部子集”,但要求查找文档“内部子集”中的默认属性值。(有关这些子集的定义,请参阅 [XML11]。)根据 UA 的不同,在 DTD 的外部子集中定义的默认属性值可能会,也可能不会出现在文档树中。

一个识别 XML 命名空间的 UA(参见 [XMLNAMESPACES])可以,但不要求使用其对该命名空间的了解,将默认属性值视为它们存在于文档中。(例如,XHTML UA 并不要求使用其对 XHTML DTD 的内置知识。)

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

示例:

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

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

如果样式表包含以下规则:

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

第一个规则可能不会匹配其“notation”属性由默认值设置的元素,即未显式设置的元素。为了捕捉所有情况,必须删除默认值的属性选择器:

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

在这里,由于选择器 EXAMPLE[notation=octal] 比单独的类型选择器更具体,因此对于“notation”属性值为“octal”的元素,第二条规则中的样式声明将覆盖第一条规则中的声明。需要注意的是,所有仅适用于默认情况的属性声明在非默认情况下的样式规则中都应被覆盖。

5.8.3 类选择器

在使用 HTML 时,作者可以使用句点(.)表示法作为表示class属性的~=表示法的替代方法。因此,对于 HTML,div.valuediv[class~=value] 具有相同的含义。属性值必须紧跟在“句点”(.)之后。如果 UA 具有特定命名空间的知识,使其能够确定哪个属性是相应命名空间的“class”属性,那么 UA 可以在 XML 文档中使用句点(.)表示法应用选择器。例如,特定命名空间的知识的一个示例是特定命名空间规范中的描述(例如,SVG 1.1 规范中描述了[SVG11]中的SVG “class” 属性及 UA 应如何解释它,类似地,MathML 3.0 中也描述了[MATH30]中的MathML “class” 属性)。

示例:

例如,我们可以将样式信息分配给所有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>

要匹配 "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 属性,则在搜索 class 之前,其值必须在值之间用空格连接。工作组目前尚未意识到可以达到这种情况的任何方式,因此此行为在本规范中明确为非规范性内容。

5.9 ID 选择器

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

文档语言的 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.1 中[XML11],关于哪个属性包含元素的 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 DTDs [XML11] 以及特定命名空间的知识来实现。

5.10 伪元素伪类

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

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

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

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

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

某些伪类是互斥的,而其他伪类可以同时应用于同一元素。在规则冲突的情况下,通常的层叠顺序将决定结果。

5.11 伪类

5.11.1 :first-child 伪类

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

示例:

在以下示例中,选择器匹配作为 DIV 元素的第一个子元素的任何 P 元素。该规则抑制了 DIV 的第一个段落的缩进:

div > p:first-child { text-indent: 0 }
该选择器将匹配以下片段中 DIV 内的 P 元素:
<P> The last P before the note.
<DIV class="note">
   <P> The first P inside the note.
</DIV>
但不会匹配以下片段中的第二个 P 元素:
<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 }

请注意,由于匿名框不是文档树的一部分,因此在计算第一个子元素时不计入它们。

例如,以下示例中的 EM:

<P>abc <EM>default</EM>
是 P 元素的第一个子元素。

以下两个选择器是等效的:

* > a:first-child   /* A 是任何元素的第一个子元素 */
a:first-child       /* 同上 */

5.11.2 链接伪类:link:visited

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

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

这两种状态是互斥的。

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

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 不定义哪些元素可以处于上述状态,或如何进入和离开这些状态。脚本可能会更改元素是否对用户事件做出反应,不同的设备和用户代理可能会有不同的方式来指向或激活元素。

CSS 2.2 不定义 ':active' 或 ':hover' 元素的父元素是否也处于该状态。

用户代理不要求因伪类转换而重新排版当前显示的文档。例如,样式表可能指定 :active 链接的字体大小应大于非活动链接的字体大小,但由于这可能导致读者选择链接时字母的位置发生变化,因此用户代理可能会忽略相应的样式规则。

示例:

例如:

a:link    { color: red }    /* 未访问的链接 */
a:visited { color: blue }   /* 已访问的链接 */
a:hover   { color: yellow } /* 悬停的链接 */
a:active  { color: lime }   /* 活动链接 */

注意,A:hover 必须放在 A:link 和 A:visited 规则之后,否则层叠规则将隐藏 A:hover 规则的颜色属性。类似地,由于 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 是否等于或是元素语言值的连字符分隔子字符串,与 '|=' 操作符的工作方式相同。C 与元素语言值的匹配对于 ASCII 范围内的字符是大小写不敏感的。C 标识符不必是有效的语言名称。

C 不得为空。

注意:建议文档和协议使用 BCP 47 中的代码 [BCP47] 或其后续版本指示语言,对于基于 XML 的文档,通过 "xml:lang" 属性来指示语言 [XML11]。参见“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>这是一个稍微长一点的 HTML 段落,它将被分成几行。第一行将通过虚构的标签序列来识别。其他行将被视为段落中的普通行。</P>

其行可能会如下划分:

这是一个稍微长一点的 HTML 段落,它
将被分成几行。第一行将通过虚构的标签
序列来识别。其他行将被视为段落中的普通行。

用户代理可能会“重写”这些行以包含用于 :first-line 的虚构的标签序列。这个虚构的标签序列有助于展示属性的继承方式。

<P><P:first-line> 这是一个稍微长一点的 HTML 段落,
将</P:first-line> 被分成几行。第一行将通过虚构的标签
序列来识别。其他行将被视为段落中的普通行。</P>

如果伪元素打断了真实元素,所需效果通常可以通过一个虚构的标签序列来描述,该序列关闭然后重新打开该元素。因此,如果我们在前面的段落中标记一个 SPAN 元素:

<P><SPAN class="test"> 这是一个稍微长一点的 HTML 段落,
将被分成几行。</SPAN> 第一行将通过虚构的标签
序列来识别。其他行将被视为段落中的普通行。</P>

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

<P><P:first-line><SPAN class="test"> 这是一个稍微长一点的 HTML 段落,
将</SPAN></P:first-line><SPAN class="test"> 被分成几行。</SPAN> 第一行将通过虚构的标签
序列来识别。其他行将被视为段落中的普通行。</P>

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

元素的“第一格式化行”可能出现在同一流中的块级后代内(即,非定位且非浮动的块级后代)。例如,<DIV><P>此行...</P></DIV> 中 DIV 的第一行是 P 的第一行(假设 P 和 DIV 都是块级的)。

表格单元格或内联块的第一行不能是祖先元素的第一格式化行。因此,在<DIV><P STYLE="display: inline-block">你好<BR>再见</P> 等等</DIV>中,DIV 的第一格式化行不是“你好”行。

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

用户代理应该表现得好像第一行伪元素的虚构起始标签刚好嵌套在最内层的块级元素内。(由于 CSS1 和 CSS2 在这种情况下保持沉默,因此作者不应依赖此行为。)以下是一个示例。以下段落的虚构标签序列为:

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

的虚构标签序列为:

<DIV>
  <P><DIV:first-line><P:first-line>第一段落</P:first-line></DIV:first-line></P>
  <P><P:first-line>第二段落</P:first-line></P>
</DIV>

:first-line 伪元素类似于内联级元素,但有某些限制。以下属性适用于 :first-line 伪元素:字体属性颜色属性背景属性单词间距字母间距文本装饰文本转换,以及行高。用户代理也可以应用其他属性。

5.12.2 The :first-letter 伪元素

:first-letter 伪元素必须选择块级元素第一行的第一个字母,如果该字母前面没有任何其他内容(如图片或内联表格)。:first-letter 伪元素可用于“首字母大写”“下沉式首字母”,这些都是常见的排版效果。如果其float属性为“none”,这种类型的首字母类似于内联级元素,否则它类似于浮动元素。

以下属性适用于 :first-letter 伪元素:字体属性文本装饰文本转换字母间距单词间距(如适用),行高浮动垂直对齐(仅当 'float' 为 'none' 时适用),边距属性填充属性边框属性颜色属性背景属性。用户代理还可以应用其他属性。为了让用户代理渲染出正确的下沉式首字母或首字母大写效果,用户代理可能会根据字母的形状选择行高、宽度和高度,而不像正常元素那样。CSS3 预计将有专门适用于首字母的属性。

以下示例展示了首字母大写的可能渲染效果。注意,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 2.2 示例将使首字母下沉,跨越约两行:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
 <HEAD>
  <TITLE>下沉首字母</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 中定义为 "open" (Ps)、"close" (Pe)、"initial" (Pi)、“final” (Pf) 和“其他” (Po) 标点符号类的字符),如果出现在首字母之前或之后,则应包含在内,如:

应该包括在首字母之前的引号。   [D]

如果首字符实际上是一个数字,例如“67 万美元是一笔巨款”,':first-letter' 也适用。

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

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

Example(s):

这是一个示例。此 HTML 片段的虚拟标签序列如下:

<div>
<p>The first text.

是:

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

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

首字母必须出现在第一格式化行上。例如,在这个片段中:<p><br>First... 第一行不包含任何字母,':first-letter' 不会匹配任何内容(假设 BR 的默认样式在 HTML4 中)。尤其是,它不会匹配“First”中的“F”。

如果一个元素是列表项('display: list-item'),':first-letter' 适用于标记后的主要框中的首字母。用户代理可能会忽略带有 'list-style-position: inside' 的列表项上的 ':first-letter'。如果一个元素有 ':before' 或 ':after' 内容,':first-letter' 适用于包含该内容的元素的首字母。

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

某些语言可能有关于如何处理某些字母组合的特定规则。例如,在荷兰语中,如果“ij”字母组合出现在单词的开头,则两个字母都应视为 :first-letter 伪元素的一部分。

如果构成首字母的字母不在同一个元素中,例如在<p>'<em>T... 中的“'T”,用户代理可以从其中一个元素、两个元素创建首字母伪元素,或者根本不创建伪元素。

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

Example(s):

以下示例说明了重叠伪元素可能如何相互作用。每个 P 元素的首字母将是绿色的,字体大小为 '24pt'。第一格式化行的其余部分将是“蓝色的”,而段落的其余部分将是“红色的”。

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 上设置了相同的属性,则会被覆盖。

5.12.3 The :before:after 伪元素

':before' 和 ':after' 伪元素可用于在元素内容的前后插入生成的内容。它们在生成文本一节中进行了说明。

Example(s):

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

当 :first-letter 和 :first-line 伪元素应用于具有使用 :before 和 :after 生成的内容的元素时,它们适用于包括生成内容的元素的首字母或首行。

Example(s):

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

这将使“Special!”中的“S”呈现为金色。