小编典典

我可以将:nth-​​child()或:nth-​​of-type()与任意选择器结合使用吗?

css

有没有办法选择 匹配(或不匹配)任意选择器的 第n个孩子?例如,我要选择每个奇数表行,但要在行的子集内:

table.myClass tr.row:nth-child(odd) {
  ...
}



<table class="myClass">
  <tr>
    <td>Row
  <tr class="row"> <!-- I want this -->
    <td>Row
  <tr class="row">
    <td>Row
  <tr class="row"> <!-- And this -->
    <td>Row
</table>

但是,无论它们是否属于“ row”类,:nth-child()似乎似乎都在计算所有tr元素,因此我最终得到了一个 偶数
row”元素,而不是我要寻找的两个元素。发生同样的事情:nth-of-type()

有人可以解释为什么吗?


阅读 498

收藏
2020-05-16

共1个答案

小编典典

由于对工作方式:nth-child():nth-of- type()工作的误解,这是一个非常普遍的问题。不幸的是,目前还没有基于选择的解决方案至今,因为选择器不提供一种方法来匹配基础上的模式,如奇数,偶数或任意选择相匹配的第n个孩子an+b,其中a != 1b != 0。这不仅限于类选择器,还包括属性选择器,取反和简单选择器的更复杂组合。

:nth-child()伪类计算中的元素
在同一母公司下的兄弟姐妹。它不只计算与选择器其余部分匹配的兄弟姐妹。类似地,:nth-of- type()伪类计数共享相同元素类型的兄弟姐妹,该元素类型引用HTML中的标签名称,而不是选择器的其余部分。

这也意味着,如果同一父级的所有子级都具有相同的元素类型,例如,在表体中其唯一的子级是tr元素,或者列表元素的唯一的子级是li元素,则:nth-child()并且:nth-of-type()将具有相同的行为,即对于每一个值an+b:nth-child(an+b)并且:nth-of-type(an+b)将匹配相同的一组元素。

实际上,给定复合选择器中的所有简单选择器,包括诸如:nth-child()和等伪类:not(),都彼此 独立
工作,而不是查看与选择器其余部分匹配的元素 子集

这也意味着 在每个单独的复合选择器 1 中的简单选择器之间没有顺序的概念 ,这意味着例如以下两个选择器是等效的:

table.myClass tr.row:nth-child(odd)
table.myClass tr:nth-child(odd).row

翻译成英文,它们的意思是:

选择tr符合以下所有独立条件的任何元素:

  • 它是其父代的奇数子代;
  • 它具有“行”类;和
  • 它是table具有“ myClass”类的元素的后代。

(您会注意到我在这里使用的是无序列表,只是为了将要点指向家)

因为目前还没有纯CSS解决方案,所以您必须使用脚本来过滤元素并相应地应用样式或额外的类名。例如,以下是使用jQuery的常见解决方法(假设在表中仅填充了一个行组tr):

$('table.myClass').each(function() {
  // Note that, confusingly, jQuery's filter pseudos are 0-indexed
  // while CSS :nth-child() is 1-indexed
  $('tr.row:even').addClass('odd');
});

使用相应的CSS:

table.myClass tr.row.odd {
  ...
}

如果您使用诸如Selenium之类的自动化测试工具,或者使用诸如lxml之类的工具来处理HTML,则其中许多工具都可以将XPath用作替代方法:

//table[contains(concat(' ', @class, ' '), ' myClass ')]//tr[contains(concat(' ', @class, ' '), ' row ')][position() mod 2)=1]

其他使用不同技术的解决方案留给读者练习。这只是一个简短的,人为的示例。


对于它的价值,有人提议将:nth-child()表示法的扩展添加到选择器级别4中,以达到选择与给定选择器匹配的第n个子代的特定目的。2:nth-child()同样,由于选择器如何按照现有选择器语法规定的顺序彼此独立地操作,因此将筛选器用来匹配的选择器作为的参数提供。因此,在您的情况下,它看起来像这样:

table.myClass tr:nth-child(odd of .row)

(精明的读者会立即注意到,应该这样做:nth-child(odd of tr.row),因为简单的选择器tr:nth- child()彼此独立运行。这是接受选择器的功能性伪类的问题之一,我会选择一堆蠕虫相反,我将假设大多数站点tr在表主体中除了元素作为彼此的同级元素外,将不具有其他任何元素,这将使两个选项在功能上都等效。)

当然,作为全新规范中的全新提案,可能要等到几年后才能实现。同时,您必须坚持使用脚本,如上所述。


1 如果指定类型或通用选择器,则必须排在最前面。但是,这不会改变选择器的基本工作方式。这不过是句法上的怪癖。

2 最初被提议为:nth-match(),但是因为它仍然仅相对于其同级而不是与给定选择器匹配的所有其他元素都相对于一个元素进行计数,因此自2014年起,该元素已被重新用作现有元素的扩展:nth-child()

2020-05-16