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

有没有一种方法可以选择每个第 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()也是如此。

有人能解释一下为什么吗?

42293 次浏览

没有。

引用文件

:nth-child伪类匹配 具有 + b-1 < strong > 兄弟节点的元素 在文档树 中,对于 给出 n 的正值或零值, 并有一个父元素。

它是自己的选择器,不与类组合。在您的规则中,它只需同时满足两个选择器,因此如果 :nth-child(even)表行碰巧也具有 .row类,那么它将显示这两个表行。

这是由于对 :nth-child(An+B):nth-of-type()如何工作的误解而产生的一个非常普遍的问题。

在选择器级别3中,:nth-child()伪类计算同一父级下兄弟节点的 所有中的元素。它不仅计算与选择器的其余部分匹配的兄弟节点。

类似地,:nth-of-type()伪类计算共享相同元素类型(在 HTML 中引用标记名称)的兄弟元素,而不计算选择器的其余部分。

这也意味着,如果同一个父元素的所有子元素都是相同的元素类型,例如,一个表主体的唯一子元素是 tr元素,或者一个列表元素的唯一子元素是 li元素,那么 :nth-child():nth-of-type()的行为将是相同的,即对于每个 A + 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元素:

  • 它是其父母的一个奇数子女;
  • 它有类“ row”; 和
  • 它是具有类“ myClass”的 table元素的后代。

(您会注意到我在这里使用了一个无序列表,这只是为了说明问题)

选择器级别4试图通过允许 :nth-child(An+B of S)2接受任意的选择器参数 S 来纠正这个限制,这也是由于选择器如何按照现有的选择器语法在复合选择器中彼此独立地操作。所以在你的例子中,它应该是这样的:

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

当然,作为一个全新规范中的全新提案,这可能要到 几年后才能实现。

同时,您必须使用脚本来过滤元素,并相应地应用样式或额外的类名。例如,下面是使用 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)或使用 BeautifulSoup 之类的工具来抓取 HTML,那么这些工具中的许多都允许 XPath 作为替代方案:

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

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


1 < sub > 如果您指定一个类型或通用选择器,它必须先出现。然而,这并没有从根本上改变选择器的工作方式; 它只不过是一种语法上的怪癖。

2 < sub > 这最初被提议为 :nth-match(),但是因为它仍然只计算相对于其兄弟元素的元素,而不是与给定选择器匹配的所有其他元素,所以从2014年开始,它被重新用作现有 :nth-child()的扩展。

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 中,我们想要隐藏所有具有 rest 类的元素。

在这种情况下,nth-childnth-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-childnth-of-type之间的区别是什么,所以这就是区别

假设 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-of-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的类型,然后他在 <p>的第1,2,3,4,5个元素上应用 css。

您可以使用 xpath 做到这一点。像 //tr[contains(@class, 'row') and position() mod 2 = 0]这样的东西可能有用。还有其他的 SO 问题扩展到如何更精确地匹配类的细节。

这就是你的答案

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>TEST</title>


<style>


.block {
background: #fc0;
margin-bottom: 10px;
padding: 10px;
}
/* .large > .large-item:nth-of-type(n+5) {
background: #f00;
} */


.large-item ~ .large-item ~ .large-item ~ .large-item ~ .large-item {
background: #f00;
}


</style>
</head>
<body>


<h1>Should be the 6th Hello Block that start red</h1>
<div class="small large">
<div class="block small-item">Hello block 1</div>
<div class="block small-item large-item">Hello block 2</div>
<div class="block small-item large-item">Hello block 3</div>
<div class="block small-item large-item">Hello block 4</div>
<div class="block small-item large-item">Hello block 5</div>
<div class="block small-item large-item">Hello block 6</div>
<div class="block small-item large-item">Hello block 7</div>
<div class="block small-item large-item">Hello block 8</div>
</div>


</body>
</html>

所有关于使用 nth-child 和跳过隐藏标签的问题似乎都是重定向的,因此我将把它留在这里。我偶然发现了这个博客 https://blog.blackbam.at/2015/04/09/css-nth-child-selector-ignore-hidden-element/,它使用了一个聪明的 css 方法来让 nth-child 忽略隐藏的元素,如下所示:

下面的 CSS 为每个第二个可见元素添加一个右边距,而不管哪个元素具有 cpw 类。

.cpw {
display:none;
}


.video_prewrap {
margin-right:20px;
}


.video_prewrap:nth-child(2n) {
margin-right:0;
}


.cpw ~ .video_prewrap:nth-child(2n) {
margin-right:20px;
}


.cpw ~ .video_prewrap:nth-child(2n-1) {
margin-right:0;
}

希望可以帮助有人谁是跟随欺骗线索为忽略隐藏的元素问题!

如果对于所有选择器都有相同的父类,则使用该类 document.querySelector("main .box-value:nth-child(3) select.priorityOption"); 因为在这种情况下 document.querySelector("main .box-value select.priorityOption:nth-child(3)");不工作。谢谢

<div class="card table">
<div class="box">
<div class="box-value">
<select class="priorityOption">
<option value="">--</option>
<option value="">LOREM</option>
<option value="">LOREM</option>
</select>
</div>


<div class="box-value">
<select class="priorityOption">
<option value="">--</option>
<option value="">LOREM</option>
<option value="">LOREM</option>
</select>
</div>


<div class="box-value">
<select class="priorityOption">
<option value="">--</option>
<option value="">LOREM</option>
<option value="">LOREM</option>
</select>
</div>
</div>
</div>

不是“有人能解释为什么吗?”的答案,因为其他答案已经解释过了。

但是,作为一种可能的解决方案,您可以为行和单元格使用自定义标记,比如 <tr-row><td-row>,然后 :nth-of-type()应该可以工作。不要忘记分别设置样式 display: table-row;display: table-cell;,使它们仍然像表格单元格一样工作。