70

I need a CSS selector that can find the 2nd div of 2 that has the same class. I've looked at nth-child() but it's not what I want since I can't see a way to further clarify what class I want. These 2 divs will be siblings in the document if that helps.

My HTML looks something like this:

<div class="foo">...</div>
<div class="bar">...</div>
<div class="baz">...</div>
<div class="bar">...</div>

And I want the 2nd div.bar (or the last div.bar would work too).

Jon Seigel
  • 12,251
  • 8
  • 58
  • 92
mpeters
  • 4,737
  • 3
  • 27
  • 41
  • 2
    strictly speaking (since you mention CSS3) :nth-of-type exists, but it's basically unsupported. http://reference.sitepoint.com/css/pseudoclass-nthoftype – annakata Jan 12 '09 at 16:41
  • 2
    @annakata I'm pretty sure `nth-of-type` wouldn't since both elements are `div`s. See this: http://jsfiddle.net/ShUHK/1/ in a modern browser. – fncomp Jul 09 '11 at 21:25

9 Answers9

77

Selectors can be combined:

.bar:nth-child(2)

means "thing that has class bar" that is also the 2nd child.

geocar
  • 9,085
  • 1
  • 29
  • 37
  • 26
    Just to make it clearer to others, this won't work because it's not the 2nd child, it's just the 2nd element that matched the `.bar` selector. So in this case `.bar:nth-child(2) would actually select the 1st `div.bar` element since it's of class "bar" and and the 2nd child of it's parent. – mpeters Apr 11 '14 at 18:16
  • Use `nth:child` to select elements of the _same parent_. – mcometa Nov 14 '15 at 07:11
  • 1
    Nth-child refers to each element present in the html dom. Just like this
    1

    2

    3

    4>
    . If you choose nth-child(2) then the heading tag

    will be selected not the 4 element. You can use nth-of-type to resolve this issue. Eg : .foo:nth-of-type(2). The given answer is completely wrong

    – Surya R Praveen Mar 14 '16 at 07:50
55

My original answer regarding :nth-of-type is simply wrong. Thanks to Paul for pointing this out.

The word "type" there refers only to the "element type" (like div). It turns out that the selectors div.bar:nth-of-type(2) and div:nth-of-type(2).bar mean the same thing. Both select elements that [a] are the second div of their parent, and [b] have class bar.

So the only pure CSS solution left that I'm aware of, if you want to select all elements of a certain selector except the first, is the general sibling selector:

.bar ~ .bar

http://www.w3schools.com/cssref/sel_gen_sibling.asp


My original (wrong) answer follows:

With the arrival of CSS3, there is another option. It may not have been available when the question was first asked:

.bar:nth-of-type(2)

http://www.w3schools.com/cssref/sel_nth-of-type.asp

This selects the second element that satisfies the .bar selector.

If you want the second and last of a specific kind of element (or all of them except the first), the general sibling selector would also work fine:

.bar ~ .bar

http://www.w3schools.com/cssref/sel_gen_sibling.asp

It's shorter. But of course, we don't like to duplicate code, right? :-)

mhelvens
  • 4,225
  • 4
  • 31
  • 55
  • This would be great if it was supported :) – mpeters Apr 11 '14 at 18:14
  • The CSS3 selectors work in [all mainstream browsers](http://caniuse.com/#feat=css-sel3) now. What kind of support are you looking for? – mhelvens Apr 11 '14 at 19:52
  • 5
    nth-of-type only works on elements, not classes. you can verify this at the w3 links above. – Paul B. Hartzog May 12 '17 at 17:54
  • 1
    @PaulB.Hartzog: Hm. You're right. I can't believe I didn't test that before I posted it in 2012. (Or did the specification change since then?) – mhelvens May 13 '17 at 13:38
  • it works perfectly! if you are using inner bootbox, that would be perfect solution for second bootbox's modal-backdrop z-index property. – Abdullah Ilgaz Sep 04 '18 at 06:27
  • Surely the general sibling selector will only work if elements are siblings of each other. How about if the 2nd of a class was somewhere else in the document? I assume this is not possible, right? – Mike Sep 11 '18 at 14:45
  • The sibling selector was just what I needed. Thanks! – mckenna Jul 26 '19 at 16:26
  • The sibling selector also worked for me, 2021. Thanks. – anthonyCam Feb 19 '21 at 23:21
31

UPDATE: This answer was originally written in 2008 when nth-of-type support was unreliable at best. Today I'd say you could safely use something like .bar:nth-of-type(2), unless you have to support IE8 and older.


Original answer from 2008 follows (Note that I would not recommend this anymore!):

If you can use Prototype JS you can use this code to set some style values, or add another classname:

// set style:
$$('div.theclassname')[1].setStyle({ backgroundColor: '#900', fontSize: '1.2em' });
// OR add class name:
$$('div.theclassname')[1].addClassName('secondclass'); // pun intentded...

(I didn't test this code, and it doesn't check if there actually is a second div present, but something like this should work.)

But if you're generating the html serverside you might just as well add an extra class on the second item...

Stein G. Strindhaug
  • 5,077
  • 2
  • 28
  • 41
  • 5
    +Stein: It turns out `nth-of-type` doesn't do what we think it does. Your new answer, like my old answer, is wrong. See my edited answer below for details. – mhelvens May 15 '17 at 23:16
  • This pseudo-class work perfect for my use case. Thanks Stain G. for answer and for the update. – Lyserty Jun 17 '19 at 18:40
17

HTML

<h1> Target Bar Elements </h1>

<div class="foo">Foo Element</div>
<div class="bar">Bar Element</div>
<div class="baz">Baz Element</div>
<div class="bar">Bar Second Element</div>
<div class="jar">Jar Element</div>
<div class="kar">Kar Element</div>
<div class="bar">Bar Third Element</div>

CSS

.bar {background:red;}
.bar~.bar {background:green;}
.bar~.bar~.bar {background:yellow;}

DEMO https://jsfiddle.net/ssuryar/6ka13xve/

Surya R Praveen
  • 3,393
  • 1
  • 24
  • 25
16

What exactly is the structure of your HTML?

The previous CSS will work if the HTML is as such:

CSS

.foo:nth-child(2)

HTML

<div>
 <div class="foo"></div>
 <div class="foo">Find me</div>
...
</div>

But if you have the following HTML it will not work.

<div>
 <div class="other"></div>
 <div class="foo"></div>
 <div class="foo">Find me</div>
 ...
</div>

Simple put, there is no selector for the getting the index of the matches from the rest of the selector before it.

Baumannzone
  • 760
  • 2
  • 19
  • 38
Seamus
  • 1,215
  • 8
  • 6
  • If I can't do it by index, is there a way to get the last item in a matched group? Since there are only 2 in this case I know that the 2nd is also the last. – mpeters Nov 20 '08 at 17:32
10

And for people who are looking for a jQuery compatible answer:

$('.foo:eq(1)').css('color', 'red');

HTML:

<div>
  <div class="other"></div>
  <div class="foo"></div>
  <div class="foo">Find me</div>
  ...    
Timon
  • 109
  • 1
  • 2
3
.parent_class div:first-child + div

I just used the above to find the second div by chaining first-child with the + selector.

Littm
  • 4,923
  • 4
  • 30
  • 38
  • 4
    That only works if the two divs are **direct** siblings. See my answer for a more general solution. Of course, your answer has the benefit of working within CSS2. – mhelvens Sep 29 '12 at 10:42
2

Is there a reason that you can't do this via Javascript? My advice would be to target the selectors with a universal rule (.foo) and then parse back over to get the last foo with Javascript and set any additional styling you'll need.

Or as suggested by Stein, just add two classes if you can:

<div class="foo"></div>
<div class="foo last"></div>

.foo {}
.foo.last {}
One Crayon
  • 19,119
  • 11
  • 33
  • 40
2

First you must select the parent element and set :nth-of-type(n) for the parent and then select the element you want. something like this :

#topmenu li:nth-of-type(2) ul.childUl {

This will select the second submenu from topmenu. #topmenu li is the parent element.

HTML:

<ul id="topmenu">
    <li>
        <ul class="childUl">
            <li></li>
            <li></li>
            <li></li>
        </ul>
    </li>
    <li>
        <ul class="childUl">
            <li></li>
            <li></li>
            <li></li>
        </ul>
    </li>
    <li>
        <ul class="childUl">
            <li></li>
            <li></li>
            <li></li>
        </ul>
    </li>

amir22
  • 413
  • 6
  • 14