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>
但是:nth-child()似乎只计算所有的tr元素,而不管它们是否是“row”类,所以我最终找到一个“row”元素,而不是我看到的对于。同样的事情发生在:nth-of-type()。
有人可以解释为什么吗?
解决方法
:nth-child()
pseudo-class计数在同一个父下的所有兄弟姐妹中的元素。它不会只计算与选择器其余部分匹配的兄弟元素。类似地,:nth-of-type()
pseudo-class计数共享同一元素类型的兄弟节点,它引用HTML中的标记名称,而不是选择器的其余部分。
这也意味着如果同一个父节点的所有子节点都是相同的元素类型,例如在只有子节点是tr元素的表体或者只有子节点是li元素的列表元素的情况下,则:nth-child ()和:nth-of-type()将表现相同,即对于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
翻译成英语,他们都是:
Select any
tr
element that matches all of the following independent conditions:
- it is an odd-numbered child of its parent;
- it has the class “row”; and
- it is a descendant of a
table
element that has the class “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(' ',' row ')][position() mod 2)=1]
使用不同技术的其他解决方案留给读者作为练习;这只是一个简单的,设计的例子。
对于什么是值得的,有一个建议an extension to the :nth-child()
notation被添加到选择器级别4为特定目的选择每个第n个孩子匹配给定的选择器2。
用于过滤匹配的选择器作为参数提供给:nth-child(),这也是由于选择器如何根据现有选择器语法所规定的在序列中彼此独立地操作。所以在你的情况下,它看起来像这样:
table.myClass tr:nth-child(odd of .row)
(精明的读者会立即注意到,这应该是:第n个孩子(tr.row的奇数),而不是简单的选择器tr和:nth-child()彼此独立操作,这是一个接受选择器的功能伪类的问题,一个蠕虫我可能不打开在这个答案的中间。而我将去假设大多数网站不会有任何其他元素,除了tr元素作为表体中的另一个的兄弟,这将使选项在功能上等同)。
当然,作为一个全新的规范中的一个全新的提案,这可能不会看到实现,直到几年下来。在此期间,你必须坚持使用一个脚本,如上所述。
1如果指定类型或通用选择器,它必须先到达。然而,这并不改变选择器的基本工作方式;它只是一个句法的怪癖。
2这最初建议为:nth-match(),但是因为它仍然计数一个元素只相对于其兄弟姐妹,而不是每个其他元素匹配给定的选择器,它自2014年以来被重用为扩展现有的:nth-child()。