CSS :nth-of-type selector breaks on non-matching c

2019-08-12 17:49发布

问题:

I have a problem with CSS :nth-of-type selector. In my code I have a list of DIVs (class "item") that should have an alternating background-color (eg. red and green). Between these items there can be some other items (class "noitem") that should not be matched from the background-color.

Problem is now, that the :nth-of-type rule breaks on every of these non-matching elements. that causes that you have one red item after the other...

Example HTML Code:

<div class="row">
  <div class="item"><h2>Item</h2></div>
  <div class="item"><h2>Item</h2></div>
  <div class="noitem"><h2>No Item</h2></div>
  <div class="item"><h2>Item</h2></div>
  <div class="item"><h2>Item</h2></div>
  <div class="item"><h2>Item</h2></div>
  <div class="item"><h2>Item</h2></div>
  <div class="noitem"><h2>No Item</h2></div>
  <div class="item"><h2>Item</h2></div>
  <div class="item"><h2>Item</h2></div>
</div>

CSS:

h2{
  font-size: 14px;
  margin: 0 0 10px 0;
  padding: 0;
}

.row .item:nth-of-type(even) h2{
  background-color: red;
}

.row .item:nth-of-type(odd) h2{
  background-color: green;
}

Can anybody help? Running example of that can be found here: http://jsfiddle.net/5qnjshg7/

回答1:

Seems impossible with CSS, unless you can change your markup and make noitem elements <span>s?

<div class="row">
    <div class="item"><h2>Item</h2></div>
    <div class="item"><h2>Item</h2></div>
    <span class="noitem"><h2>No Item</h2></span>
    <div class="item"><h2>Item</h2></div>
    <div class="item"><h2>Item</h2></div>
    <div class="item"><h2>Item</h2></div>
    <div class="item"><h2>Item</h2></div>
    <span class="noitem"><h2>No Item</h2></span>
    <div class="item"><h2>Item</h2></div>
    <div class="item"><h2>Item</h2></div>
</div>


回答2:

The type in nth-of-type refers to the type of element (tag name, such as div). It does not mean "nth-of-something-with-exactly-the-same-classes", or "nth-of-the-selector-I-specified", which does not exist in CSS.

In other words, .item:nth-of-type(even) does not mean "an even-numbered entry in the list of all child elements with class .item", but rather, "an element with class .item which also is in an even-numbered position in the list of all child elements of that type (div in this case), regardless of their class or anything else".

One possible approach if you're stuck with the existing HTML

If you can generate different HTML, including for example new classes, or replacing the div on noitem elements with spans, as one answer suggested, then that is the best solution. In case you are not able to do or don't want to do that, and need to work with the existing HTML for whatever reason, this bit of JS will do the job:

var elts = document.querySelectorAll('div.item');
for (var i = 0; i < elts.length; i++) {
    elts[i].classList.add(i % 2 ? 'red' : 'green');
}


回答3:

nth-of-type matches the element to its parent, so although it is not the same selector, it is in fact the correct index relevant to its parent.