nth-child doesn't respond to class [duplicate]
Asked Answered
P

3

68

Is it possible to get the nth-child pseudo-selector to work with a specific class?

See this example: http://jsfiddle.net/fZGvH/

I want to have the second DIV.red turn red, but it doesn't apply the color as expected.

Not only that, but when you specify this, it changes the 5th DIV to red:

div.red:nth-child(6)

When you specify this, it changes the 8th DIV to red:

div.red:nth-child(9)

It seems to be one DIV behind. There are only 8 DIV tags in the example so I don't know why nth-child(9) even works. Testing using Firefox 3.6, but in my actual production code the same problem occurs in Chrome. I'm not understanding something about how this is supposed to work, would appreciate clarification.

Also, this will change the 6th DIV to red, but what I actually want is for it to change the second DIV.red to red:

div.red:nth-of-type(6)

And I don't understand why nth-child() and nth-of-type() respond differently, since there are only eight tags of the same type in the document.

Pronty answered 25/3, 2011 at 4:52 Comment(5)
div.red:nth-child(9) doesn't cause anything to be red. I tried it on your fiddle (note that you can place CSS in the CSS panel instead of in <style> tags).Crossway
This is very strange. Have you tried it outside of fiddle? There is something happening with what seems like the body tag not acting as the parent. I added a <span> as a container around all of the <div> tags and the nth-child selectors acted as expected.Destructive
@ckaufman, yes, I did try it locally and that's why (as @Crossway pointed out) everything is in one pane. I was copying+pasting back and forth, trying to see the problem. But it works the same. The HTML is valid but something's weird, and it's working the same way in the app I'm coding. Even with a proper header [jsfiddle.net/runnC/] the code works the same – (9) is actually (8), (3) is actually (2), etc.Pronty
@BoltClock, please try again, when I try div.red:nth-child(9) the 8th div turns red. div:nth-child(2) turns the first div orange. Can't figure it out but as I said it's working the same way in the app, kind of weird.Pronty
Marking this as a dupe of a question that was originally posted about a week later, but mostly because that question is more general and thus contains a more canonical answer than this one.Crossway
C
63

There's no way to filter by class in CSS because there's no :nth-of-class() selector. One way around this is to put your two different kinds of divs into their own groups, then select based on those groups. For example:

<div class="orange">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

<div class="red">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

With this selector:

div.red div:nth-child(2) {
    background: red;
}

Regarding the last bit of your question:

And I don't understand why nth-child() and nth-of-type() respond differently, since there are only eight tags of the same type in the document.

For the code you give there shouldn't be any difference. I tested it, and the two pseudo-classes work as expected. But, in general:

:nth-child() operates on an entire level of siblings without regard for any other simple selectors. Then if the nth child is not among what's matched by the simple selectors, nothing is matched.

:nth-of-type() operates on a level of siblings of the given type without regard for other simple selectors. Then if the nth element occurring of that type is not among what's matched by the simple selectors, nothing is matched.

Crossway answered 25/3, 2011 at 5:10 Comment(6)
I think this is really what I was looking for – :nth-of-class doesn't exist. It seems like .red:nth-child(2) would be natural CSS syntax but it doesn't work as expected. Too bad, because it would be really useful.Pronty
i tried this method and i still cant seem to get it to work, have a look jsfiddle.net/BUWaZBaseburner
@Baseburner Look at jsfiddle.net/BUWaZ/19 You were trying to search the 3rd child of the first li.Marinna
.classname:nth-child(1n){... works on the first .classname on the pageAnadiplosis
I know your answer in the linked dupe mentions the more complex nth-child selector, but it might be worth mentioning here also as it is the first question that came up when I searched this topic. Also, hi!Tuneful
@Zach Saucier: Hello. Feel free to attach a note to my answer. I've kind of stopped maintaining most of my answers on here, and I barely visit the site more than a couple of times a year now. I hope you are well!Crossway
G
11

You can use the general sibling combinator:

div,
div.red ~ div.red ~ div.red {
  background: gray;
}
div.red ~ div.red {
  background: red;
}

It is verbose and you need to reset the styles back again, but it could be useful in some special situations.

It could be automated with a CSS preprocessor, and if I understand gzip correctly, since the CSS ouput is just repeating the same text the gziped file size should not be terribly big unless you use it a lot.

Germinative answered 24/5, 2012 at 10:54 Comment(0)
H
5

there's a simpler solution that I have found to work with my divs without any special lines of code.

.red div:nth-child(6) {background-color:#ccc;}
.red div:nth-child(9) {background-color:#eee;}

works just fine as well without the div in front.

Harness answered 1/12, 2012 at 4:10 Comment(2)
This doesn't work. jsfiddle.net/Lf6a7fxh/1 The first div.colorme should've been blue, but it's not, because the first div without a class name is taken into account.Harridan
@Harridan is rightAdventitious

© 2022 - 2024 — McMap. All rights reserved.