孩子()或:nth
有没有办法选择匹配(或不匹配)任意选择器的每个第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>
但是:nth-child()
似乎要计算所有tr
元素,无论它们是否属于“row”类,所以我最终得到了一个“row”元素,而不是我正在寻找的两个元素对于。 同样的事情发生在:nth-of-type()
。
有人能解释为什么吗?
这是一个非常普遍的问题,这是由于误解了如何:nth-child()
和:nth-of-type()
。 不幸的是,目前还没有基于选择的解决方案至今,因为选择器不提供一种方法来匹配基于图案任意选择匹配,如奇数,偶数或第n个子an+b
其中a != 1
和b != 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
元素的后代。 (你会注意到我在这里使用了一个无序的列表,只是为了将这个观点带回家)
由于目前没有纯粹的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个孩子的具体目的。
用来过滤匹配的选择器作为参数提供给: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()
代替。
不是真的..
从文档引用
:nth-child
伪类匹配在文档树中具有+ b-1 兄弟元素之前的元素,对于给定的正值或零值,并且具有父元素。
它是自己的选择器,并不与类组合。 在你的规则中,它必须同时满足两个选择器,所以它将显示:nth-child(even)
表格行,如果它们碰巧具有.row
类。
nth-of-type
根据元素的相同类型的索引工作,但是nth-child
只根据索引工作,不管哪个类型的同类元素都是。
例如
<div class="one">...</div>
<div class="two">...</div>
<div class="three">...</div>
<div class="four">...</div>
<div class="five">...</div>
<div class="rest">...</div>
<div class="rest">...</div>
<div class="rest">...</div>
<div class="rest">...</div>
<div class="rest">...</div>
假设在上面的html中我们想要隐藏所有具有休息类的元素。
在这种情况下, nth-child
和nth-of-type
将完全相同,因为所有元素都是相同类型的<div>
所以css应该是
.rest:nth-child(6), .rest:nth-child(7), .rest:nth-child(8), .rest:nth-child(9), .rest:nth-child(10){
display:none;
}
要么
.rest:nth-of-type(6), .rest:nth-of-type(7), .rest:nth-of-type(8), .rest:nth-of-type(9), .rest:nth-of-type(10){
display:none;
}
现在你一定想知道nth-child
和nth-of-type
nth-child
之间有什么区别,所以这是不同的
假设html是
<div class="one">...</div>
<div class="two">...</div>
<div class="three">...</div>
<div class="four">...</div>
<div class="five">...</div>
<p class="rest">...</p>
<p class="rest">...</p>
<p class="rest">...</p>
<p class="rest">...</p>
<p class="rest">...</p>
在上面的html中, .rest
元素的类型与其他人不同.rest
是段落,其他人是div,所以在这种情况下,如果你使用nth-child
你必须这样写
.rest:nth-child(6), .rest:nth-child(7), .rest:nth-child(8), .rest:nth-child(9), .rest:nth-child(10){
display:none;
}
但如果你使用nth-type- css可以这样
.rest:nth-of-type(1), .rest:nth-of-type(2), .rest:nth-of-type(3), .rest:nth-of-type(4), .rest:nth-of-type(5){
display:none;
}
由于类型.rest
元件是<p>
所以在这里nth-of-type
被检测的类型.rest
然后他所施加的第一,第二,第三,第四,第五的元件上的CSS <p>
上一篇: child() or :nth