nth-child calculating incorrectly

I have a set of divs, I want every third one to have no margin on the right hand side. Naturally, I assumed div:nth-child(3n) would work. It does not. I did some research and it seems like it's counting all the elements in the parent div when calculating which to affect. The result is it's targeting not every third div, but every third element that happens to be a div. To elaborate, take a look at this http://jsfiddle.net/3wV9p/3/ .

<style type="text/css>
    div:nth-child {
        background-color: blue;
        color: white;
    }
</style>
<h1>Hello World</h1>
<p>A paragrapgh tag.</p>
<p>A second paragrapgh tag</p>
<p>I want these to be ignored.</p>
<p>I just want every third div (3, 6, 9, 12) to be blue.</p>
<div>The 1st div.</div>
<div>The 2nd div.</div>
<div>The 3rd div.</div>
<div>The 4th div.</div>
<div>The 5th div.</div>
<div>The 6th div.</div>
<div>The 7th div.</div>
<div>The 8th div.</div>
<div>The 9th div.</div>
<div>The 10th div.</div>
<div>The 11th div.</div>
<div>The 12th div.</div>

Assuming I want every third div to be blue, how do I compensate for the fact that it's counting the p and h1 tags? I realize I could just offset by the number of other elements (5 in this case) but in the context i need to use this, the preceding elements are dynamically generated so it's not possible to know what the offset would need to be.

To sum up then, I need a way to count JUST the elements I care about not every element of the same level. Is that even possible with CSS or will I need to implement some JS/jQuery? The really frustrating part is none of the documentation I've found on nth-child() even comes close to indicating that it functions in this manner. I had to figure it out myself via trial and error.

Problem courtesy of: Daniel Clarke

Solution

The only way you can compensate for the irrelevant elements is to use a different selector. The :nth-child() selector is working as intended here, because your p and h1 elements are all siblings of your div elements, sharing the same parent (that is, the body element).

In this case, since the only difference between them is the element type, you can use :nth-of-type() instead :

div:nth-of-type(3n) {
    background-color: blue;
    color: white;
}

In more complicated cases, such as when you have div elements with differing class names, attributes, etc, you will not be able to count just the elements you want with pure CSS. This is because there is no :nth-of-class() or other such selector, or a way of counting just the elements that match some arbitrary condition/selector. See my answer to this question for a more detailed explanation.

jQuery makes up for this limitation somewhat with an :eq() selector , but it works very differently from :nth-child() and :nth-of-type() , and may not always provide a sufficient replacement. There is no CSS equivalent of jQuery's :eq() . See this answer for an explanation of the differences.

Solution courtesy of: BoltClock

Discussion

You can use nth-of-type option. nth-of-type selects the element of that type matching the n . So in the below example it would select every 3rd div element.

div:nth-of-type(3n){
    background-color: blue;
    color: white;
}

Demo

Discussion courtesy of: Harry

This recipe can be found in it's original form on Stack Over Flow .

我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章