Home  >  Q&A  >  body text

A method that can be combined with any selector is to use another selector in the pseudo-class :nth-child() or :nth-of-type()

<p>Is there a way to select every nth child element that satisfies (or does not satisfy) an arbitrary selector? For example, I want to select every odd table row, but within a subset of rows: </p> <pre class="brush:css;toolbar:false;">table.myClass tr.row:nth-child(odd) { ... } </pre> <pre class="brush:html;toolbar:false;"><table class="myClass"> <tr> <td>Row <tr class="row"> <!-- I want this --> <td>Row <tr class="row"> <td>Row <tr class="row"> <!-- And this one --> <td>Row </table> </pre> <p>But <code>:nth-child()</code> only seems to count all <code>tr</code> elements regardless of whether they are of type "row", so I end up What I get is one <em>even</em> "row" element, not the two I'm looking for. The same thing happens with <code>:nth-of-type()</code>. </p> <p>Can anyone explain why? </p>
P粉926174288P粉926174288406 days ago550

reply all(2)I'll reply

  • P粉466643318

    P粉4666433182023-08-15 14:26:12

    not real..

    Quote from documentation

    It is an independent selector and is not combined with a class. In your rule, it only needs to satisfy both selectors, so if the :nth-child(even) table row also has the .row class, it will be displayed.

    reply
    0
  • P粉563446579

    P粉5634465792023-08-15 11:04:17

    This is a very common question and is caused by a misunderstanding of how :nth-child(An B) and :nth-of-type() work caused.

    In selector level 3, :nth-child()Pseudo class calculates the position among all sibling elements under the same parent element, not just Is a sibling element that matches the rest of the selector.

    Similarly, :nth-of-type()pseudoclasscalculates sibling elements that share the same element type, which is an indicator signature in HTML, and Not the rest of the selector.

    This also means that if all child elements of the same parent element are of the same element type, for example, the table body has only tr elements or the list element has only li elements, then # The behavior of ##:nth-child() and :nth-of-type() will be the same, i.e. for each value of An B, :nth-child( An B) and :nth-of-type(An B) will match the same set of elements.

    In fact, all simple selectors in a given compound selector, including pseudo-classes such as

    :nth-child() and :not(), are Standalone works instead of looking at the subset of elements matched by the rest of the selector.

    This also means that

    Within each individual compound selector, there is no concept of order between simple selectors1, which means that for example the following two selectors are equivalent:

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

    Translated into English, they all mean:

    (You will notice that I used an unordered list here, just to emphasize the point)

    Selector level 4 attempts to correct this limitation by allowing

    :nth-child(An B of S)2 to accept arbitrary selector arguments S, This is because the selectors operate independently within the compound selector, as determined by the existing selector syntax. So in your case it would be like this:

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

    Of course, as a completely new proposal in a completely new specification, this may not be implemented until

    several years.

    In the meantime, you will need to use scripts to filter elements and apply styles or extra class names accordingly. For example, here is a common workaround using jQuery (assuming there is only one row group in the table containing the

    tr element):

    $('table.myClass').each(function() {
      // 注意,令人困惑的是,jQuery的过滤伪类是从0开始索引的,而CSS的:nth-child()是从1开始索引的
      $('tr.row:even').addClass('odd');
    });
    The corresponding CSS for

    is:

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

    If you are using an automated testing tool such as Selenium, or using a tool such as BeautifulSoup to parse HTML, many of these tools allow the use of XPath as an alternative:

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

    Other solutions using different techniques are left as an exercise to the reader; this is just a brief, deliberate example.


    1 If a type or universal selector is specified, it must come first. However, this doesn't change the basic workings of selectors; it's just a syntax quirk.

    2 Originally proposed was :nth-match(), however, since it still only computes elements relative to their siblings, not to those that satisfy the given selector for every other element, so since 2014 it has been reused as an extension to the existing :nth-child().

    reply
    0
  • Cancelreply