9.4 按上下文选择元素

在CSS中,可以根据元素的祖先、父元素或同胞元素来定位它们(参见1.3节中的“父元素和子元素”),如图9.4.1~图9.4.4所示。

祖先(ancestor)是包含目标元素(后代,descendant)的任何元素,不管它们之间隔了多少代。

  1. 按祖先元素选择要格式化的元素
  • 输入ancestor,这里的ancestor是希望格式化的元素的祖先元素的选择器。

  • 输入一个空格。

  • 如果需要,对后续的每个祖先元素重复第1步和第2步。

  • 输入descendant,这里的descendant是希望格式化的元素的选择器。

  1. ...
  2. <article class="about">
  3. <h1>Antoni Gaudí</h1>
  4.  
  5. <p>Many tourists ... </p>
  6. <p>Barcelona ... </p>
  7.  
  8. <section class="project">
  9. <h2 lang="es">La Casa Milà</h2>
  10. <p>Gaudí's work ... </p>
  11. </section>
  12.  
  13. <section class="project">
  14. <h2 lang="es">La Sagrada Família</h2>
  15. ...
  16. </section>
  17. </article>
  18. ...

图9.4.1 为了让元素之间的关系更为明显,我对文本做了删节。每一级缩进代表一代。注意,在这段代码中,有两个直接包含在article里的属于about类的第二代p元素,一个直接包含在属于project类的section(包含在article里)的第三代p元素。此外,还有一个第三代p元素,但没有显示出来。h2也都是第三代。代码实现参见图9.4.6

  1. article.about p {
  2. color: red;
  3. }

图9.4.2 article.aboutp之间的空格意味着这个选择器会寻找任何作为about类的article的后代的p元素,不管它是第几代元素。不过,在class前面添加元素名称通常会带来更高的特殊性,而在实践中往往并不需要这么高的特殊性(对id来说更是如此)。关于特殊性较低的选择器,参见图9.4.3

  1. /* 得到相同效果的其他方式
  2. -------------------------------------- */
  3.  
  4. /* 任意article后代的所有p, 特殊性最低的方法 */
  5. article p {
  6. color: red;
  7. }
  8.  
  9. /* 任意about类元素后代的所有p, 特殊性第二低的方法 */
  10. .about p {
  11. color: red;
  12. }

图9.4.3 构造选择器以达到预期效果通常有一种以上的方法。关键在于你需要多大的特殊性。这里第一个例子中的选择器(article p { })的特殊性比它后面的选择器(.about p { })和图9.4.2中选择器的特殊性都低。这里第二个例子结合了class选择器和后代选择器(也可以与id选择器结合)。你将发现一直使用的是这些选择器,而不是图9.4.2中更特殊和冗长的模式

9.4 按上下文选择元素 - 图1

图9.4.4 所有包含在属于about类的元素里的p元素都是红色的,即使它们同时也包含于其他属于about类的元素。图9.4.2和图9.4.3中每条样式规则的结果都显示在这里

提示 基于元素祖先的选择器称为后代选择器。CSS3将其重命名为后代结合符(有的人仍称其为“选择器”)。

 

提示 不要对图9.4.2中的article.about部分感到疑惑。记住这只表示“class等于aboutarticle”。因此article.about p表示“包含在class等于aboutarticle元素里的任何p元素”。相比之下,特殊性低一些的.about p表示“包含在class等于about的任意元素里的所有p元素”,参见图9.4.3。这是因为在上下文中id选择器的特殊性比元素和类选择器的更高。

上面的例子展示了后代结合符。CSS也有子结合符,从而可以为父元素的直接后代(即子元素)定义样式规则。在CSS3之前,它们称做子选择器。父元素是直接包含另一元素(子元素)的元素,也即它们之间没有隔着任何层次。

  1. 按父元素选择要格式化的元素
  • 输入parent,这里的parent是直接包含待格式化元素的元素的选择器。

  • 输入>(大于号),参见图9.4.5。

  • 如果需要,对后续每代父元素重复第1步和第2步。

  • 输入child,这里的child是要格式化的元素的选择器。

  1. article.about > p {
  2. color: red;
  3. }

图9.4.5 这个选择器仅选择作为aboutarticle元素的子元素(而非子子元素、子子子元素等)的p元素。包含于任何其他元素的p元素均不会被选中,实现参见图9.4.6

9.4 按上下文选择元素 - 图2

图9.4.6 只有头两个p元素是aboutarticle的子元素。另两个p元素是articlesection元素的子元素。这个例子使用的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)。

  1. /* 你可能认为这会让第一个段落变成红色, 但实际上不会! */
  2.  
  3. .about > p:first-child {
  4. color: red;
  5. }

图9.4.7 :first-child伪类仅选择某元素的第一个子元素,而不是作为子元素的元素的第一个实例。因此,也许你倾向于认为下面的规则会让示例页面中的第一个段落显示为红色,但实际上不是这样(参见图9.4.8),因为h1才是aboutarticle的第一个子元素。这个例子使用的HTML代码见图9.4.1

9.4 按上下文选择元素 - 图3

图9.4.8 这条规则对页面没有任何影响,因为没有一个p元素是about类元素的子元素

  1. /* h1是第一个子元素,因此是有效的 */
  2.  
  3. .about > h1:first-child {
  4. color: red;
  5. }

图9.4.9 这个选择器仅选择作为在HTML中带有class="about"的元素的第一个子元素的h1。这条规则会影响页面的显示,参见图9.4.10

9.4 按上下文选择元素 - 图4

图9.4.10 包含在article里的h1显示为红色,因为它是某个about类元素的第一个子元素。如果article里还有其他h1元素,这些元素将不会显示为红色

  1. 选择某元素的第一个子元素进行格式化
  • 这一步可选,输入parent,这里的parent是目标元素的父元素的选择器。

  • 如果在第1步中包含了parent,就再依次输入一个空格、>和另一个空格。

  • 可选,输入表示要格式化的第一个子元素的选择器(如p.news)。

  • 输入:first-child(参见图9.4.9)。(注意,第1步中指定parent并不是必需的。例如,使用p:first-child { font-weight: bold; }会为每一个作为某元素第一个子元素的段落添加粗体样式。)

下面继续讲我们的“家族”主题。同胞元素(sibling)是拥有同一父元素的任何类型的子元素。相邻同胞元素(adjacent sibling)是直接相互毗邻的元素,即它们之间没有其他的同胞元素。在下面这个简略的例子中,h1p是相邻同胞元素,ph2是相邻同胞元素,而h1h2则不是相邻同胞元素。不过,它们都是同胞元素(也是body元素的子元素)。

  1. ...
  2. <body>
  3. <h1>...</h1>
  4. <p>...</p>
  5. <h2>...</h2>
  6. </body>
  7. </html>

CSS相邻同胞结合符(adjacent sibling combinator)可以选择直接跟在指定的同胞元素后面的同胞元素。(关于CSS3中新出现的普通同胞结合符(general sibling combinator),参见最后一条提示。)

  1. 按相邻同胞元素选择要格式化的元素
  • 输入sibling,这里的sibling是包含在同一父元素中的、直接出现在目标元素前面的元素的选择器。(它们不必是同一种元素类型,只要它们彼此直接相邻就行。)

  • 输入+(加号)。

  • 如有需要,对每个后续的同胞元素重复第1步和第2步。

  • 输入element,这里的element是要格式化的元素的选择器,参见图9.4.11。

  1. .about p+p {
  2. color: red;
  3. }

图9.4.11 这个相邻同胞结合符仅选择直接出现在同胞p元素后面的p元素

提示 另参见第1章“父元素和子元素”。

 

提示 选择器中的:first-child部分称为伪类,因为它标识的是你(设计人员或开发人员)无需在HTML代码中标记的一组元素。

 

提示 IE 6既不支持:first-child,也不支持相邻同胞选择器。

9.4 按上下文选择元素 - 图5

图9.4.12 只有直接跟在同胞p元素后面的p元素显示为红色。如果后面还有第三个、第四个以及更多的段落,它们也将显示为红色。例如,如果要对除第一个段落以外的所有段落进行缩进,相邻同胞结合符就很有用

提示 CSS3引入了普通同胞结合符,通过它可以选择不一定直接出现在另一同胞元素后面的同胞元素。它与相邻同胞结合符的唯一区别是使用~(波浪号)代替+分隔同胞元素。例如,h1~h2 { color: red; }会让任何属于同一父元素的同胞h1后面的h2元素显示为红色(它们可以直接相邻,也可以不直接相邻),参见图9.4.12。