这是一个非常常见的问题,因为误解了:nth-child(An+B)
和:nth-of-type()
的工作原理.
在3级 Select 器中,:nth-child()
pseudo-class个元素在同一父项下的all个sibling 姐妹中计数.它不仅计算与 Select 器其余部分匹配的同级.类似地,:nth-of-type()
pseudo-class统计共享相同元素类型的sibling 姐妹,该元素类型指的是HTML中的标记名,而不是 Select 器的其余部分.
这也意味着,如果相同父代的所有子代都属于相同的元素类型,例如,在唯一子代为tr
个元素的表体或唯一子代为li
个元素的列表元素的情况下,:nth-child()
和:nth-of-type()
的行为将是相同的,即对于每个+B的值,:nth-child(An+B)
和:nth-of-type(An+B)
将匹配相同的元素集.
事实上,给定复合 Select 器中的所有简单 Select 器,包括诸如:nth-child()
和:not()
之类的伪类,都是彼此相加的,而不是查看 Select 器的睡觉匹配的subsetof元素.
这还意味着there is no notion of order among simple selectors within each individual compound selector1,这意味着例如以下两个 Select 符是等效的:
table.myClass tr.row:nth-child(odd)
table.myClass tr:nth-child(odd).row
翻译成英语,它们都意味着:
Select 符合以下所有独立条件的任何tr
元素:
- 它是其父对象的奇数子对象;
- 它有类"ROW";以及
- 它是具有类"myClass"的
table
元素的后代.
(您会注意到我在这里使用了无序列表,只是为了说明问题)
Select 器级别4试图通过允许:nth-child(An+B of S)
2接受任意 Select 器参数S来纠正此限制,这也是由于 Select 器如何按照现有 Select 器语法的规定在复合 Select 器中彼此独立地操作.因此,在您的情况下,它将如下所示:
table.myClass tr:nth-child(odd of .row)
当然,作为全新规范中的一个全新提议,这可能要到a few years down the road年才能实现.
同时,您必须使用脚本来过滤元素,并相应地应用样式或额外的类名.例如,以下是使用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)或将HTML与BeautifulSoup等工具结合使用,这些工具中的许多都允许使用XPath作为替代工具:
//table[contains(concat(' ', @class, ' '), ' myClass ')]//tr[contains(concat(' ', @class, ' '), ' row ')][position() mod 2)=1]
使用不同技术的其他解决方案留给读者作为练习;这只是一个简短的人为设计的示例.
1 If you specify a type or universal selector, it must come first. This does not change how selectors fundamentally work, however; it's nothing more than a syntactic quirk.
2 This was originally proposed as :nth-match()
, however because it still counts an element relative only to its siblings, and not to every other element that matches the given selector, it has since as of 2014 been repurposed as an extension to the existing :nth-child()
instead.