css - 我可以合并 :nth-child() or :nth-of-type() with an arbitrary selector? 吗

标签 css css-selectors

有没有办法选择匹配(或不匹配)任意选择器的第 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 元素,不管它们是否属于“行”类,所以我结束了使用一个偶数“行”元素,而不是我正在寻找的两个。 :nth-of-type() 也会发生同样的事情。

谁能解释一下为什么?

最佳答案

这是一个非常常见的问题,由于对 :nth-child(An+B):nth-of-type() 工作方式的误解而产生.

在选择器级别 3 中,:nth-child() pseudo-class计算同一父级下所有 sibling 中的元素。它不只计算匹配其余选择器的兄弟。

同样,:nth-of-type() pseudo-class计算共享相同元素类型的 sibling ,它指的是 HTML 中的标记名称,而不是选择器的其余部分。

这也意味着如果同一个父元素的所有子元素都是相同的元素类型,例如在表体的情况下,其唯一的子元素是 tr 元素,或者列表元素只有children 是 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

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

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".

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

选择器级别 4 试图通过允许 :nth-child(An+B of S) 来纠正此限制。 2 接受任意选择器参数 S,这也是由于选择器如何在复合选择器中独立于另一个操作,正如现有选择器语法所规定的那样。所以在你的情况下,它看起来像这样:

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)或使用 BeautifulSoup 等工具抓取 HTML,其中许多工具都允许使用 XPath 作为替代:

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

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


1 如果指定类型或通用选择器,它必须在前面。然而,这并没有改变选择器的基本工作方式。这只不过是一个句法怪癖。

2 这最初是作为 :nth-match() 提出的,但是因为它仍然只计算与其兄弟相关的元素,而不是每个元素与给定选择器匹配的其他元素,自 2014 年起,它已被重新用作现有 :nth-child() 的扩展。

关于css - 我可以合并 :nth-child() or :nth-of-type() with an arbitrary selector? 吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50680022/

相关文章:

javascript - 将类别添加到标签

html - 固定页眉和页脚具有 100% 可滚动内容

javascript - 单击列表元素符号时禁用列表突出显示

css - 使用 nth :child 将 CSS 声明应用于多个元素

css - 为什么作用域样式没有加载到 nuxt 页面中?

html - Matches() 选择器不工作

CSS all that start with chaining - CSS select all IDs that start with "u"and are in :hover and control other id that start with u

CSS 更短的查询

中心的 HTML 对齐图例元素在 Internet Explorer 和 Firefox 中不起作用

javascript - JQuery 粘条在页面调整大小时闪烁