4

Maybe this question is ridiculous, but I want to know this fact. I have a li element with two classes (see below), but it is not working as I expected. Does anybody know the reason?

.red:first-child {
    color:#F00;
}
.blue:first-child {
    color:#00F; /* not working */
}
.red:last-child {
    color:#F00; /* not working */
}
.blue:last-child {
    color:#00F; 
}
<ul>
    <li class="red">one</li> <!-- This is the first child of red -->
    <li class="red">two</li>
    <li class="red">three</li>
    <li class="blue">one</li> <!-- and this first child of blue -->
    <li class="blue">two</li>
    <li class="blue">three</li>
</ul>

18
  • 2
    Its working as expected. <li class="blue">one</li> is not the first-child of parent ul
    – Satpal
    Commented Jan 2, 2017 at 7:19
  • 1
    @Satpal: no its not working as expected... Commented Jan 2, 2017 at 7:20
  • 1
    Problem exists in wrong understanding of :first-child or :last-child selector. They will select any element only when an element is first or last child element of its parent respectively. Commented Jan 2, 2017 at 7:25
  • 1
    Your selector .blue:first-child is not working because .blue is not first child of parent. This is the thinking behind implementation of this selector and as for me its quite logical. Commented Jan 2, 2017 at 7:27
  • 2
    @mnemosdev: No, ul:first-child matches the ul in much the same way ul.example (with a class selector) matches the ul. It doesn't match other elements. Likewise, .red:first-child matches whichever element has the .red class, not its parent, or its child.
    – BoltClock
    Commented Jan 2, 2017 at 9:03

3 Answers 3

6

As others have mentioned, :first-child is working as expected, as the first child of the parent.

The :first-child selector is used to select the specified selector, only if it is the first child of its parent.

Source: CSS :first-child Selector

You can reach the first .blue like this:

.red + .blue

or if you want to get all the .blue after .red

.red ~ .blue

You might want to use :first-of-type which selects the first of a type but then those .blue would have to be a different HTML element.

div.red:first-of-type {
    color:#F00;
}
div.red:last-of-type {
    color:#00F;
}
p.blue:first-of-type {
    color:#F00;
}
p.blue:last-of-type {
    color:#00F; 
}
<div>
    <div class="red">one</div>
    <div class="red">two</div>
    <div class="red">three</div>
    <p class="blue">one</p>
    <p class="blue">two</p>
    <p class="blue">three</p>
</div>

3
  • Nope. :first-of-type doesn't look at the class either.
    – BoltClock
    Commented Jan 2, 2017 at 8:45
  • You are right @BoltClock, it doesn't. There is no option to do so with class as far as I know. You could however reach the first blue with those other selectors I included in the answer.
    – Alvaro
    Commented Jan 2, 2017 at 9:02
  • I agree. I do think that :first-of-type shouldn't even be considered since a ul can only have li as children (which means both pseudo-classes will always match the same element), and I just personally don't like changing the HTML to fit a CSS selector. But I removed my downvote.
    – BoltClock
    Commented Jan 2, 2017 at 9:06
0

Because It consider Li list. First you have to mention first-childs so take first command to show red. THen Take last code as blue last-child so take last code to show blue.

It not consider the red and blue class orders. It consider li list and periorities.

2
  • that is my question, why its not considering the class wise
    – Jishnu V S
    Commented Jan 2, 2017 at 7:24
  • It consider only the paren and child elements like ul as parent and li as child. Not taking class.
    – Dhaarani
    Commented Jan 2, 2017 at 7:29
0

It doesn't work because what you said to the browser was (for the red case, the blue one is similar):

  1. Locate all elements .red.
  2. From that list of .red elements, pick the first one (first-child).
  3. Apply the red color to it.

The browser works as expected and apply the red color to the first element of the list.

EDIT:

The blue case is due to the fact that CSS always looks for the most precise rule. If both rules has the same precision level, the last one wins, so in this case, the last .blue:last-child wins and the .blue:first-child is ignored.

4
  • "the blue one is similar" And that's why the asker expects .blue:first-child to match the first .blue element. But it doesn't.
    – BoltClock
    Commented Jan 2, 2017 at 8:45
  • Sorry, I didn't read it, "mea culpa". In that case, both selectors has the same "precision level", I mean, they aren't more precise than each other, so "the last one" rule applies and the one colored is the last blue.
    – amedina
    Commented Jan 2, 2017 at 8:50
  • This has nothing to do with specificity. Specificity does not preclude both .blue:first-child and .blue:last-child matching different elements (or the same element) at the same time.
    – BoltClock
    Commented Jan 2, 2017 at 8:53
  • @BoltClock You are right. Here's a codepen with the order changed.
    – amedina
    Commented Jan 2, 2017 at 9:09

Not the answer you're looking for? Browse other questions tagged or ask your own question.