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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5545649/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 00:08:01  来源:igfitidea点击:

Can I combine :nth-child() or :nth-of-type() with an arbitrary selector?

csscss-selectors

提问by atanamir

Is there a way to select every nth child that matches (or does not match) an arbitrary selector? For example, I want to select every odd table row, but within a subset of the rows:

有没有办法选择匹配(或不匹配)任意选择器的每个第 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>

But :nth-child()just seems to count all the trelements regardless of whether or not they're of the "row" class, so I end up with the one even"row" element instead of the two I'm looking for. The same thing happens with :nth-of-type().

:nth-child()似乎只是计算所有tr元素,而不管它们是否属于“行”类,所以我最终得到了一个甚至“行”元素,而不是我正在寻找的两个元素。同样的事情发生在:nth-of-type().

Can someone explain why?

有人可以解释为什么吗?

回答by BoltClock

This is a very common problem that arises due to a misunderstanding of how :nth-child()and :nth-of-type()work. Unfortunately, there is currently no selector-based solution as yet because Selectors does not provide a way to match the nth child that matches an arbitrary selector based on a pattern such as odd-numbered, even-numbered or any an+bwhere a != 1and b != 0. This extends beyond just class selectors, to attribute selectors, negations, and more complex combinations of simple selectors.

这是由于对工作方式:nth-child():nth-of-type()工作方式的误解而出现的一个非常普遍的问题。不幸的是,目前还没有基于选择器的解决方案,因为选择器没有提供一种方法来匹配第 n 个子节点,该子节点匹配基于诸如奇数、偶数或任何an+bwherea != 1和等模式的任意选择器b != 0。这不仅扩展到类选择器,还扩展到属性选择器、否定和简单选择器的更复杂组合。

The :nth-child()pseudo-classcounts elements among allof their siblings under the same parent. It does not count only the siblings that match the rest of the selector. Similarly, the :nth-of-type()pseudo-classcounts siblings sharing the same element type, which refers to the tag name in HTML, and not the rest of the selector.

:nth-child()伪类计算中的元素在同一母公司下的兄弟姐妹。它不只计算与选择器其余部分匹配的兄弟姐妹。类似地,:nth-of-type()伪类计算共享相同元素类型的兄弟姐妹,它指的是 HTML 中的标签名称,而不是选择器的其余部分。

This also means that if all the children of the same parent are of the same element type, for example in the case of a table body whose only children are trelements or a list element whose only children are lielements, then :nth-child()and :nth-of-type()will behave identically, i.e. for every value of an+b, :nth-child(an+b)and :nth-of-type(an+b)will match the same set of elements.

这也意味着,如果同一父级的所有子级都具有相同的元素类型,例如在表体的唯一子级是tr元素或列表元素的唯一子级是li元素的情况下,则:nth-child():nth-of-type()将表现相同,即对于每一个值an+b:nth-child(an+b)并且:nth-of-type(an+b)将匹配相同的一组元素。

In fact, all simple selectors in a given compound selector, including pseudo-classes such as :nth-child()and :not(), work independentlyof one another, rather than looking at the subsetof elements that are matched by the rest of the selector.

事实上,给定复合选择器中的所有简单选择器,包括伪类,如:nth-child()and :not(),彼此独立工作,而不是查看与选择器其余部分匹配的元素子集

This also implies that there is no notion of order among simple selectors within each individual compound selector1, which means for example the following two selectors are equivalent:

这也意味着在每个单独的复合选择器1中的简单选择器之间没有顺序的概念,这意味着例如以下两个选择器是等效的:

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

Translated to English, they both mean:

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

Select any trelement 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 tableelement that has the class "myClass".

选择tr符合以下所有独立条件的任何元素:

  • 它是其父级的奇数子级;
  • 它有“行”类;和
  • 它是table具有“myClass”类的元素的后代。

(you'll notice my use of an unordered list here, just to drive the point home)

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

Because there is currently no pure CSS solution, you'll have to use a script to filter elements and apply styles or extra class names accordingly. For example, the following is a common workaround using jQuery (assuming there is only one row group populated with trelements within the 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');
});

With the corresponding CSS:

使用相应的 CSS:

table.myClass tr.row.odd {
  ...
}

If you're using automated testing tools such as Selenium or processing HTML with tools like lxml, many of these tools allow XPath as an alternative:

如果您使用 Selenium 等自动化测试工具或使用 lxml 等工具处理 HTML,其中许多工具都允许 XPath 作为替代方案:

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

Other solutions using different technologies are left as an exercise to the reader; this is just a brief, contrived example for illustration.

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



For what it's worth, there is a proposal for an extension to the :nth-child()notationto be added to Selectors level 4 for the specific purpose of selecting every nth child matching a given selector.2

就其价值而言,有一项提议:nth-child()符号的扩展添加到选择器级别 4,用于选择与给定选择器匹配的每个第 n 个子项的特定目的。2

The selector by which to filter matches is provided as an argument to :nth-child(), again due to how selectors operate independently of one another in a sequence as dictated by the existing selector syntax. So in your case, it would look like this:

过滤匹配的选择器作为参数提供给:nth-child(),同样是由于选择器如何按照现有选择器语法规定的顺序彼此独立运行。所以在你的情况下,它看起来像这样:

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

(An astute reader will note right away that this ought to be :nth-child(odd of tr.row)instead, since the simple selectors trand :nth-child()operate independently of one another as well. This is one of the problems with functional pseudo-classes that accept selectors, a can of worms I'd rather not open in the middle of this answer. Instead I'm going to go with the assumption that most sites will not have any other elements than trelements as siblings of one another in a table body, which would make either option functionally equivalent.)

(精明的读者会立即注意到,这应该是:nth-child(odd of tr.row)相反的,因为简单的选择器tr:nth-child()彼此独立的操作也是如此。这是接受选择器的功能伪类的问题之一,我会的一罐蠕虫而不是在这个答案的中间打开。相反,我将假设大多数站点除了tr作为表体中彼此兄弟的元素之外没有任何其他元素,这将使任一选项在功能上等效。)

Of course, being a brand new proposal in a brand new specification, this probably won't see implementation until a few years down the road. In the meantime, you'll have to stick with using a script, as above.

当然,作为全新规范中的全新提案,这可能要到几年后才会实施。与此同时,您必须坚持使用脚本,如上所述。



1If 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.

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

2This 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.

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

回答by Gabriele Petrioli

Not really..

并不真地..

quote from the docs

来自文档的引用

The :nth-childpseudo-class matches an element that has an+b-1 siblings before it in the document tree, for a given positive or zero value for n, and has a parent element.

:nth-child伪类相匹配,其具有+ B-1的元素的兄弟姐妹之前它在文档树,对于一个给定的正或对于n零值,且具有父元素。

It is a selector of its own and does not combine with classes. In your rule it just has to satisfy both selector at the same time, so it will show the :nth-child(even)table rows if they also happen to have the .rowclass.

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

回答by Gaurav Aggarwal

nth-of-typeworks according to the index of same type of the element but nth-childworks only according to index no matter what type of siblings elements are.

nth-of-type根据元素的相同类型的索引工作,但nth-child无论兄弟元素是什么类型,都只根据索引工作。

For example

例如

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

Suppose in above html we want to hide all the elements having rest class.

假设在上面的 html 中我们想要隐藏所有具有 rest 类的元素。

In this case nth-childand nth-of-typewill work exactly same as all the element are of same type that is <div>so css should be

在这种情况下,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;
}

OR

或者

.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;
}

Now you must be wondering what is the difference between nth-childand nth-of-typeso this is the difference

现在你一定想知道它们之间有什么区别nth-childnth-of-type所以这就是区别

Suppose the html is

假设 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>

In the above html the type of .restelement is different from others .restare paragraphs and others are div so in this case if you use nth-childyou have to write like this

在上面的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;
}

but if you use nth-of-typecss can be this

但是如果你使用 nth-of-typecss 可以是这个

.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;
}

As type of .restelement is <p>so here nth-of-typeis detecting the type of .restand then he applied css on the 1st, 2nd, 3rd, 4th, 5th element of <p>.

由于.rest元素的类型<p>如此,这里nth-of-type是检测的类型,.rest然后他在 的第 1、2、3、4、5 个元素上应用 css <p>

回答by the8472

You may be able to do that with xpath. something like //tr[contains(@class, 'row') and position() mod 2 = 0]might work. There are other SO questions expanding on the details how to match classes more precisely.

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

回答by Pocketninja

Here is your answer

这是你的答案

<!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>

回答by IrishDubGuy

All of the questions around using nth-child and skipping hidden tags appear to be redirecting as dupes of this one so I will leave this here. I came across this blog https://blog.blackbam.at/2015/04/09/css-nth-child-selector-ignore-hidden-element/that uses a clever css approach to make nth-child ignore hidden elements, as follows:

所有关于使用 nth-child 和跳过隐藏标签的问题似乎都被重定向为这个人的骗子,所以我将把它留在这里。我遇到了这个博客https://blog.blackbam.at/2015/04/09/css-nth-child-selector-ignore-hidden-element/它使用巧妙的 css 方法使 nth-child 忽略隐藏元素,如下:

The following CSS adds a margin right to every second visible element no matter which element has the cpw class.

无论哪个元素具有 cpw 类,以下 CSS 都会为每个第二个可见元素添加一个边距。

.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;
}

Hope that helps someone who is following the dupe trail for the ignore hidden elements questions!

希望能帮助那些正在追踪忽略隐藏元素问题的人!

回答by Jatin Aggarwal

IF you have same parent class for all selector, Then you use that class document.querySelector("main .box-value:nth-child(3) select.priorityOption");Because in that case document.querySelector("main .box-value select.priorityOption:nth-child(3)");Not working. Thank You

如果所有选择器都具有相同的父类,那么您将使用该类,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>