How to select the first, second, or third element with a given class name?

How can I select a certain element in a list of elements? I have the following:

<div class="myclass">my text1</div>
<!-- some other code follows -->
<div>
    <p>stuff</p>
</div>
<div>
    <p>more stuff</p>
</div>
<p>
    <span>Hello World</span>
</p>
<div class="myclass">my text2</div>
<!-- some other code follows -->
<div>
    <p>stuff</p>
</div>
<p>
    <span>Hello World</span>
</p>
<input type=""/>
<div class="myclass">my text3</div>
<!-- some other code follows -->
<div>
    <p>stuff</p>
</div>
<footer>The end</footer>

I have the CSS class div.myclass {doing things} that applies to all, obviously, but I also wanted to be able to select the first, second, or third div of class .myclass like this, regardless of where they are in the markup:

div.myclass:first {color:#000;} 
div.myclass:second {color:#FFF;} 
div.myclass:third {color:#006;}

Almost like the jQuery index selection .eq( index ), which is what I am using currently, but I need a no-script alternative.

To be specific, I am looking for pseudo selectors, not things like adding another class or using IDs to make things work.


Solution 1:

use nth-child(item number) EX

<div class="parent_class">
    <div class="myclass">my text1</div>
    some other code+containers...

    <div class="myclass">my text2</div>
    some other code+containers...

    <div class="myclass">my text3</div>
    some other code+containers...
</div>
.parent_class:nth-child(1) { };
.parent_class:nth-child(2) { };
.parent_class:nth-child(3) { };

OR

:nth-of-type(item number) same your code

.myclass:nth-of-type(1) { };
.myclass:nth-of-type(2) { };
.myclass:nth-of-type(3) { };

Solution 2:

You probably finally realized this between posting this question and today, but the very nature of selectors makes it impossible to navigate through hierarchically unrelated HTML elements.

Or, to put it simply, since you said in your comment that

there are no uniform parent containers

... it's just not possible with selectors alone, without modifying the markup in some way as shown by the other answers.

You have to use the jQuery .eq() solution.

Solution 3:

Yes, you can do this. For example, to style the td tags that make up the different columns of a table you could do something like this:

table.myClass tr > td:first-child /* First column */
{
  /* some style here */
}
table.myClass tr > td:first-child+td /* Second column */
{
  /* some style here */
}
table.myClass tr > td:first-child+td+td /* Third column */
{
  /* some style here */
}

Solution 4:

This isn't so much an answer as a non-answer, i.e. an example showing why one of the highly voted answers above is actually wrong.

I thought that answer looked good. In fact, it gave me what I was looking for: :nth-of-type which, for my situation, worked. (So, thanks for that, @Bdwey.)

I initially read the comment by @BoltClock (which says that the answer is essentially wrong) and dismissed it, as I had checked my use case, and it worked. Then I realized @BoltClock had a reputation of 300,000+(!) and has a profile where he claims to be a CSS guru. Hmm, I thought, maybe I should look a little closer.

Turns out as follows: div.myclass:nth-of-type(2) does NOT mean "the 2nd instance of div.myclass". Rather, it means "the 2nd instance of div, and it must also have the 'myclass' class". That's an important distinction when there are intervening divs between your div.myclass instances.

It took me some time to get my head around this. So, to help others figure it out more quickly, I've written an example which I believe demonstrates the concept more clearly than a written description: I've hijacked the h1, h2, h3 and h4 elements to essentially be divs. I've put an A class on some of them, grouped them in 3's, and then colored the 1st, 2nd and 3rd instances blue, orange and green using h?.A:nth-of-type(?). (But, if you're reading carefully, you should be asking "the 1st, 2nd and 3rd instances of what?"). I also interjected a dissimilar (i.e. different h level) or similar (i.e. same h level) un-classed element into some of the groups.

Note, in particular, the last grouping of 3. Here, an un-classed h3 element is inserted between the first and second h3.A elements. In this case, no 2nd color (i.e. orange) appears, and the 3rd color (i.e. green) shows up on the 2nd instance of h3.A. This shows that the n in h3.A:nth-of-type(n) is counting the h3s, not the h3.As.

Well, hope that helps. And thanks, @BoltClock.

div {
  margin-bottom: 2em;
  border: red solid 1px;
  background-color: lightyellow;
}

h1,
h2,
h3,
h4 {
  font-size: 12pt;
  margin: 5px;
}

h1.A:nth-of-type(1),
h2.A:nth-of-type(1),
h3.A:nth-of-type(1) {
  background-color: cyan;
}

h1.A:nth-of-type(2),
h2.A:nth-of-type(2),
h3.A:nth-of-type(2) {
  background-color: orange;
}

h1.A:nth-of-type(3),
h2.A:nth-of-type(3),
h3.A:nth-of-type(3) {
  background-color: lightgreen;
}
<div>
  <h1 class="A">h1.A #1</h1>
  <h1 class="A">h1.A #2</h1>
  <h1 class="A">h1.A #3</h1>
</div>

<div>
  <h2 class="A">h2.A #1</h2>
  <h4>this intervening element is a different type, i.e. h4 not h2</h4>
  <h2 class="A">h2.A #2</h2>
  <h2 class="A">h2.A #3</h2>
</div>

<div>
  <h3 class="A">h3.A #1</h3>
  <h3>this intervening element is the same type, i.e. h3, but has no class</h3>
  <h3 class="A">h3.A #2</h3>
  <h3 class="A">h3.A #3</h3>
</div>

Solution 5:

Perhaps using the "~" selector of CSS?

.myclass {
    background: red;
}

.myclass~.myclass {
    background: yellow;
}

.myclass~.myclass~.myclass {
    background: green;
}

See my example on jsfiddle