Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

:last-child not working as expected?

The issue lies within this CSS and HTML. Here is a link to jsFiddle with the sample code.

HTML

<ul>     <li class"complete">1</li>     <li class"complete">2</li>     <li>3</li>     <li>4</li> </ul> 

CSS

li.complete:last-child {     background-color:yellow; }  li.complete:last-of-type {     background-color:yellow; } 

Shouldn't either of these lines of CSS target the last li element with the "complete" class?

This query in jQuery doesn't target it either:

$("li.complete:last-child"); 

But this one does:

$("li.complete").last(); 

li {    background-color: green;  }  li.complete:first-child {    background-color: white;  }  li.complete:first-of-type {    background-color: red;  }  li.complete:last-of-type {    background-color: blue;  }  li.complete:last-child {    background-color: yellow;  }
<ul>    <li class="complete">1</li>    <li class="complete">2</li>    <li>3</li>    <li>4</li>  </ul>
like image 732
Nej Kutcharian Avatar asked Sep 25 '13 02:09

Nej Kutcharian


1 Answers

The last-child selector is used to select the last child element of a parent. It cannot be used to select the last child element with a specific class under a given parent element.

The other part of the compound selector (which is attached before the :last-child) specifies extra conditions which the last child element must satisfy in-order for it to be selected. In the below snippet, you would see how the selected elements differ depending on the rest of the compound selector.

.parent :last-child{ /* this will select all elements which are last child of .parent */    font-weight: bold;  }    .parent div:last-child{ /* this will select the last child of .parent only if it is a div*/    background: crimson;  }    .parent div.child-2:last-child{ /* this will select the last child of .parent only if it is a div and has the class child-2*/    color: beige;  }
<div class='parent'>    <div class='child'>Child</div>    <div class='child'>Child</div>    <div class='child'>Child</div>    <div>Child w/o class</div>  </div>  <div class='parent'>    <div class='child'>Child</div>    <div class='child'>Child</div>    <div class='child'>Child</div>    <div class='child-2'>Child w/o class</div>  </div>  <div class='parent'>    <div class='child'>Child</div>    <div class='child'>Child</div>    <div class='child'>Child</div>    <p>Child w/o class</p>  </div>

To answer your question, the below would style the last child li element with background color as red.

li:last-child{     background-color: red; } 

But the following selector would not work for your markup because the last-child does not have the class='complete' even though it is an li.

li.complete:last-child{     background-color: green; } 

It would have worked if (and only if) the last li in your markup also had class='complete'.


To address your query in the comments:

@Harry I find it rather odd that: .complete:last-of-type does not work, yet .complete:first-of-type does work, regardless of it's position it's parents element. Thanks for your help.

The selector .complete:first-of-type works in the fiddle because it (that is, the element with class='complete') is still the first element of type li within the parent. Try to add <li>0</li> as the first element under the ul and you will find that first-of-type also flops. This is because the first-of-type and last-of-type selectors select the first/last element of each type under the parent.

Refer to the answer posted by BoltClock, in this thread for more details about how the selector works. That is as comprehensive as it gets :)

like image 152
Harry Avatar answered Oct 18 '22 16:10

Harry