9.4 按上下文选择元素
在CSS中,可以根据元素的祖先、父元素或同胞元素来定位它们(参见1.3节中的“父元素和子元素”),如图9.4.1~图9.4.4所示。
祖先(ancestor)是包含目标元素(后代,descendant)的任何元素,不管它们之间隔了多少代。
- 按祖先元素选择要格式化的元素
输入
ancestor
,这里的ancestor
是希望格式化的元素的祖先元素的选择器。输入一个空格。
如果需要,对后续的每个祖先元素重复第1步和第2步。
输入
descendant
,这里的descendant
是希望格式化的元素的选择器。
- ...
- <article class="about">
- <h1>Antoni Gaudí</h1>
- <p>Many tourists ... </p>
- <p>Barcelona ... </p>
- <section class="project">
- <h2 lang="es">La Casa Milà</h2>
- <p>Gaudí's work ... </p>
- </section>
- <section class="project">
- <h2 lang="es">La Sagrada Família</h2>
- ...
- </section>
- </article>
- ...
图9.4.1 为了让元素之间的关系更为明显,我对文本做了删节。每一级缩进代表一代。注意,在这段代码中,有两个直接包含在article
里的属于about
类的第二代p
元素,一个直接包含在属于project
类的section
(包含在article
里)的第三代p
元素。此外,还有一个第三代p
元素,但没有显示出来。h2
也都是第三代。代码实现参见图9.4.6
- article.about p {
- color: red;
- }
图9.4.2 article.about
和p
之间的空格意味着这个选择器会寻找任何作为about
类的article
的后代的p
元素,不管它是第几代元素。不过,在class
前面添加元素名称通常会带来更高的特殊性,而在实践中往往并不需要这么高的特殊性(对id
来说更是如此)。关于特殊性较低的选择器,参见图9.4.3
- /* 得到相同效果的其他方式
- -------------------------------------- */
- /* 任意article后代的所有p, 特殊性最低的方法 */
- article p {
- color: red;
- }
- /* 任意about类元素后代的所有p, 特殊性第二低的方法 */
- .about p {
- color: red;
- }
图9.4.3 构造选择器以达到预期效果通常有一种以上的方法。关键在于你需要多大的特殊性。这里第一个例子中的选择器(article p { }
)的特殊性比它后面的选择器(.about p { }
)和图9.4.2中选择器的特殊性都低。这里第二个例子结合了class
选择器和后代选择器(也可以与id
选择器结合)。你将发现一直使用的是这些选择器,而不是图9.4.2中更特殊和冗长的模式
图9.4.4 所有包含在属于about
类的元素里的p
元素都是红色的,即使它们同时也包含于其他属于about
类的元素。图9.4.2和图9.4.3中每条样式规则的结果都显示在这里
提示 基于元素祖先的选择器称为后代选择器。CSS3将其重命名为后代结合符(有的人仍称其为“选择器”)。
提示 不要对图9.4.2中的
article.about
部分感到疑惑。记住这只表示“class
等于about
的article
”。因此article.about p
表示“包含在class
等于about
的article
元素里的任何p
元素”。相比之下,特殊性低一些的.about p
表示“包含在class
等于about
的任意元素里的所有p
元素”,参见图9.4.3。这是因为在上下文中id
选择器的特殊性比元素和类选择器的更高。
上面的例子展示了后代结合符。CSS也有子结合符,从而可以为父元素的直接后代(即子元素)定义样式规则。在CSS3之前,它们称做子选择器。父元素是直接包含另一元素(子元素)的元素,也即它们之间没有隔着任何层次。
- 按父元素选择要格式化的元素
输入
parent
,这里的parent
是直接包含待格式化元素的元素的选择器。输入
>
(大于号),参见图9.4.5。如果需要,对后续每代父元素重复第1步和第2步。
输入
child
,这里的child
是要格式化的元素的选择器。
- article.about > p {
- color: red;
- }
图9.4.5 这个选择器仅选择作为about
类article
元素的子元素(而非子子元素、子子子元素等)的p
元素。包含于任何其他元素的p
元素均不会被选中,实现参见图9.4.6
图9.4.6 只有头两个p
元素是about
类article
的子元素。另两个p
元素是article
里section
元素的子元素。这个例子使用的HTML代码见图9.4.1
提示 正如你在后代结合符中看到的,可以忽略
class
前面的元素名称。事实上,这也是推荐的做法(除非为实现目标样式需要额外的特殊性)。例如,使用.about > p { color: red; }
会产生同样的效果。也可以完全不用class
,如article > p { color: red; }
,产生更低的特殊性。在考虑特殊性更高的选择器之前,应当尽可能地使用这些更为简单的形式。本章剩余部分的一些例子也可以按类似的方式进行简化。你已经了解了如何进行简化,因此不必再一一列举这些替代方案,但应记住,通常最好保持较低的特殊性,让样式更易于复用。
提示 也可以在子结合符中使用
id
选择器,但推荐尽量使用特殊性更低的选择器(如元素类型、class
等)。
提示 Internet Explorer 6不支持子选择器。
有时,只选择元素的第一个子元素(而不是所有的子元素)是很有用的。要实现这种效果,可以使用:first-child
伪类(参见图9.4.7~图9.4.10)。
- /* 你可能认为这会让第一个段落变成红色, 但实际上不会! */
- .about > p:first-child {
- color: red;
- }
图9.4.7 :first-child
伪类仅选择某元素的第一个子元素,而不是作为子元素的元素的第一个实例。因此,也许你倾向于认为下面的规则会让示例页面中的第一个段落显示为红色,但实际上不是这样(参见图9.4.8),因为h1
才是about
类article
的第一个子元素。这个例子使用的HTML代码见图9.4.1
图9.4.8 这条规则对页面没有任何影响,因为没有一个p
元素是about
类元素的子元素
- /* h1是第一个子元素,因此是有效的 */
- .about > h1:first-child {
- color: red;
- }
图9.4.9 这个选择器仅选择作为在HTML中带有class="about"
的元素的第一个子元素的h1
。这条规则会影响页面的显示,参见图9.4.10
图9.4.10 包含在article
里的h1
显示为红色,因为它是某个about
类元素的第一个子元素。如果article
里还有其他h1
元素,这些元素将不会显示为红色
- 选择某元素的第一个子元素进行格式化
这一步可选,输入
parent
,这里的parent
是目标元素的父元素的选择器。如果在第1步中包含了
parent
,就再依次输入一个空格、>
和另一个空格。可选,输入表示要格式化的第一个子元素的选择器(如
p
或.news
)。输入
:first-child
(参见图9.4.9)。(注意,第1步中指定parent
并不是必需的。例如,使用p:first-child { font-weight: bold; }
会为每一个作为某元素第一个子元素的段落添加粗体样式。)
下面继续讲我们的“家族”主题。同胞元素(sibling)是拥有同一父元素的任何类型的子元素。相邻同胞元素(adjacent sibling)是直接相互毗邻的元素,即它们之间没有其他的同胞元素。在下面这个简略的例子中,h1
和p
是相邻同胞元素,p
和h2
是相邻同胞元素,而h1
和h2
则不是相邻同胞元素。不过,它们都是同胞元素(也是body
元素的子元素)。
...
<body>
<h1>...</h1>
<p>...</p>
<h2>...</h2>
</body>
</html>
CSS相邻同胞结合符(adjacent sibling combinator)可以选择直接跟在指定的同胞元素后面的同胞元素。(关于CSS3中新出现的普通同胞结合符(general sibling combinator),参见最后一条提示。)
- 按相邻同胞元素选择要格式化的元素
输入
sibling
,这里的sibling
是包含在同一父元素中的、直接出现在目标元素前面的元素的选择器。(它们不必是同一种元素类型,只要它们彼此直接相邻就行。)输入+(加号)。
如有需要,对每个后续的同胞元素重复第1步和第2步。
输入
element
,这里的element
是要格式化的元素的选择器,参见图9.4.11。
- .about p+p {
- color: red;
- }
图9.4.11 这个相邻同胞结合符仅选择直接出现在同胞p
元素后面的p
元素
提示 另参见第1章“父元素和子元素”。
提示 选择器中的
:first-child
部分称为伪类,因为它标识的是你(设计人员或开发人员)无需在HTML代码中标记的一组元素。
提示 IE 6既不支持
:first-child
,也不支持相邻同胞选择器。
图9.4.12 只有直接跟在同胞p
元素后面的p
元素显示为红色。如果后面还有第三个、第四个以及更多的段落,它们也将显示为红色。例如,如果要对除第一个段落以外的所有段落进行缩进,相邻同胞结合符就很有用
提示 CSS3引入了普通同胞结合符,通过它可以选择不一定直接出现在另一同胞元素后面的同胞元素。它与相邻同胞结合符的唯一区别是使用~(波浪号)代替+分隔同胞元素。例如,
h1~h2 { color: red; }
会让任何属于同一父元素的同胞h1
后面的h2
元素显示为红色(它们可以直接相邻,也可以不直接相邻),参见图9.4.12。