Is it possible to target the most recent list item in CSS?

I have a page menu that will be similar in structure to the following nested list:

<ul> <li>Page 1</li> <li>Page 2</li> <li> Page 3 <ul> <li>Subpage 1</li> <li>Subpage 2</li> <!-- Can I target ONLY this element? --> </ul> </li> </ul> 

Please note that this list is dynamic. The number of elements and the number of levels are not predictable . So something like this will not be flexible enough:

 /* I know this does not have great browser support - just an example */ ul > li > ul > li:last-child { /* CSS here */ } 

I understand that I can change the server code to add a class to the last element, but first I would like to know if this is possible in CSS.

To complicate matters, I’d like to target all major browsers along with IE 7+.

Can I target the last element of a list using CSS?

Basically, I need this Fiddle solved (via @ Pumbaa80).

+7
source share
5 answers

CSS3 Path (IE9 +)

If you know exactly how deep your last element is, you can redo your calls to :last-child :

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

This pseudo-class selector is not supported in IE prior to version 9, according to http://caniuse.com/#search=last-child . Of course, if you don’t know how deep this list item will be, then this method is not very useful.

JavaScript method

You can also target the last element of the list using JavaScript:

 var items = document.getElementById("mylist").getElementsByTagName("li"), _item = items[ items.length - 1 ]; _item.className == "" ? _item.className = "last" : _item.className += " last" ; 

This is raw JavaScript that does not require additional frameworks or libraries. If you use a popular framework like jQuery, this could be even simpler:

 $("#mylist li:last").addClass("last"); 

I would not suggest you use jQuery just for something like that. Raw JavaScript will be much faster and much less bloated.

Preprocessor method

Depending on how your navigation menu is configured, you can use the server language to identify the last item in the list and mark it as such. For example, we could do the following using the DOMDocument class in PHP:

 $d = new DOMDocument(); $d->loadHTML( $html ); $a = $d->getElementsByTagName("li"); $l = $a->item( $a->length - 1 ); $c = $l->getAttribute("class"); empty( $c ) ? $l->setAttribute("class", "last") : $l->setAttribute("class", "last $c"); echo $d->saveHTML( $l ); 

This finds the last element of the list in HTML and adds a new β€œlast” class to it. The advantage of this is that it does not require a complex and often ineffective CSS3 selector. Furthermore, it does not require the addition of large JavaScript libraries to accomplish trivial things.

+6
source

You sent the correct path:

 li:last-child 

If you need to be sure you can use javascript / jQuery for this. But then you may have a problem: "If people have js disabled?" ... no.

Use li:last-child .


Edit:

If you can add an atleast class on UL , this will be easy. Otherwise, if you will definitely have only two lists:

 ul ul li:last-child { /* code */ } 

Other Edit:

http://jsfiddle.net/toroncino/4NXg2/

Double solution, js and css.


Change again:

Your fiddle: http://jsfiddle.net/toroncino/NaJas/1/

 $('ul').last().addClass('last');​ 
+5
source

In short: no. The limitations you give make CSS solutions inappropriate because of (very) poor support for "advanced css" in IE7.

Can javascript be used in your case? With jquery, the following occurs to you:

 $('ul li').last().css('color', 'red'); 

edit: This will also bypass your problem with an unknown tree depth, since the children of the last li will automatically be further in the list of matching elements, but the children of the previous li will not:

  • 1st element
  • Second element
  • Third element
    • 4th element
  • Fifth Element

edit: I updated your fiddle here http://jsfiddle.net/NaJas/4/

+1
source

It's impossible. Your limitation

The number of elements and the number of levels are not predictable.

means that CSS2 selectors and even CSS3 selectors are not enough:

Suppose you have a selector that works for the depth of list 2. Now adding the third level of the list to this element will invalidate this selector, i.e. the selector will have to depend on the children of the element. Selectors like this don't exist yet, and will be introduced in CSS4 , where this will be the solution to your problem:

 /* CSS4 */ li:last-child:not($li li) { /**/ } 

The $li li selector means "a li that has some descendant li ".

+1
source

You can use li: last-child in your CSS

0
source

All Articles