Using jQuery to mimic CSS3's :nth-last-child

I came across the need for using CSS3′s :nth-last-child pseudo-selector recently. What does this do? Nth-last-child lets you select the nth (2nd, 3rd, 4th, etc) child of some element starting from the last one. For example:

li:nth-last-child(-n+4) would select the last four list items in a list.

To style the 2nd-to-last list item only, this example would work:

li:nth-last-child(-n+2)

The situation I had was there is a list of authors for a site. More than wp_list_authors, it was a custom-generated list of certain users. The list is styled to look like a box with two columns. There are dividers between each author both horizontally and vertically, with the bottom two authors having no bottom divider.

This list:

<ul id="authors">
	<li class="even"><span><a class="authorImg" href="">
	  <img src="avatar.jpg" height="30px" alt="" /></a>
	    <a class="authorName" href="">John Doe</a></span></li>
	<li class="odd"><span><a class="authorImg" href="">
	  <img src="avatar.jpg" height="30px" alt="" /></a>
	    <a class="authorName" href="">Hap Pill</a></span></li>
...(snip)...
	<li class="odd"><span><a class="authorImg" href="">
	  <img src="avatar.jpg" height="30px" alt="" /></a>
	    <a class="authorName" href="">John Hancock</a></span></li>
	<li class="even"><span><a class="authorImg" href="">
	  <img src="avatar.jpg" height="30px" alt="" /></a>
	    <a class="authorName" href="">Lorem Ipsum</a></span></li>
	<li class="odd"><span><a class="authorImg" href="">
	  <img src="avatar.jpg" height="30px" alt="" /></a>
	    <a class="authorName" href="">Jane Doe</a></span></li>
</ul>

… needs to look like this:

Removing the border on the last list item’s span is easy. Use the :last-child pseudo-selector and the border’s gone.

#authors li.odd:last-child span {
	border-bottom: none;
	}

Removing the border on the 2nd-to-last one should be this easy:

#authors li:nth-last-child(-n+2) span {
	border-bottom: none;
	}

But for now, that only works in Safari 4. (and maybe Opera?) so how to get that effect in Safari 3 and Firefox 3? (I have not gotten this to work in IE7 or 6. Those are coming.) Use jQuery and a three-line script.

Here’s what I cobbled together from digging through the jQuery documentation:

//removes bottom border from next-to-last span in the authors listings
	var $curr = $('#authors li:last');
	$curr = $curr.prev().children('span');
	$curr.css('border-bottom','none');

The script first locates the last list item. Then it looks for the previous element of that type, then drills down to the children elements that are spans. In this case, there’s only one. Lastly, the script applies a CSS rule of no border to the span.

Is it perfect? Almost. I’ll need to figure out how to get IE7 and, unfortunately for this job, IE6 to render the next-to-last item correctly.

Tags: , , ,

2 Responses to “Using jQuery to mimic CSS3's :nth-last-child”

  1. Nice! Too bad that darn IE always spoils the party (FWIW, Firefox adds :nth-* in v3.5 http://hacks.mozilla.org/2009/06/css3-nth/).

    Would IE play nice if you apply a “lastRow” class to the last li elements and then style the “li.lastRow span” selector?

    // goal: add classes to the last row of list items so that we can use CSS  to remove the bottom border
    $(function(){
      // add the 'lastRow' class to the last
      $('#authors li:last').addClass('lastRow')
        // then check to see if the previous  has the 'even' class already present
        // before adding a lastRow class to it
        .prev().filter('.even').addClass('lastRow');
    });

    And then the CSS looks like:

    #authors li.lastRow span {
        border-bottom: none;
    }
  2. Patrick says:

    Steve, I need to dig some more, because I’m getting two different behaviors from this code in IE7 on two sites where I use this trick. Your idea looks like it’d work fine, so that might be the bulletproof trick for IE7 & IE6.

Leave a Reply