2007-11-15

Using Prototype to emulate :last-child on IE6

Usually it's easy to find a CSS hack to deal with Internet Explorer's oddities... not so with the :last-child pseudo element, at least as far as I can tell. But using the Prototype javascript library, I was able to build a suitable replacement in 3 lines of code (it could have been 1 if I didn't care about readability or expandability).

Here's my scenario. I have a list of items, and I'm using CSS to turn them into a simple horizontal menu (see here to explain). To the right of each item, I want a vertical bar (like a |) but properly aligned, and not on the last item. So, I used the following css, putting a right-hand border on all but the last element:

ul.menu {
float: left;
padding: 0;
margin: 0;
list-style: none;
}

ul.menu li {
float: left;
position: relative;
padding: 0px 5px;
border-right: 1px solid #E00000;
}


ul.menu li:last-child {
border-right: 0;
}

...
<ul class="menu">
<li>First Menu Item</li>
<li>Second</li>
<li>Etc..</li>
</ul>


The results: perfect in Firefox, not so in IE6: the last item in the list still has a border, because the :last-child pseudo-element isn't supported.

So, instead, I'm using the following javascript (this won't work without Prototype):

document.getElementsByClassName('menu').each(function(menu) {
$($(menu.immediateDescendants()).last()).setStyle({borderRight: '0'});
});


Bingo! No border-right on the last menu item, in IE or Firefox. Yay!

2 comments:

  1. hi, congratulation for the post. i'm facing a problem related and i hope u could help me. i've tried to use the code u posted and he prototype.js but the right border of my horzontal menu its still there.heres a fragment of my code:

    ==language="JavaScript"==
    document.getElementByID('HouseMenuNavList').each(function(HouseMenuNavList) {
    $($(HouseMenuNavList.immediateDescendants()).last()).setStyle({ borderRight: '0' });
    });

    ====================

    div id="HouseMenuNav"
    ul id="HouseMenuNavList"
    li id="item1" li
    li id="item2" li
    li id="item3" li
    ul
    div

    obs: i removed the open and close tag character because they are not allowed here in blogger.

    can u help me?? whats wrong in my code??

    any help or tip is welcome! :)

    ReplyDelete
  2. @Rodrigo

    If you use the following CSS and script, the right border on the last list item will be hidden in IE8 (and presumably in IE6 too)

    The CSS:

    #HouseMenuNavList {
    float: left;
    padding: 0;
    margin: 0;
    list-style: none;
    }

    #HouseMenuNavList li {
    float: left;
    position: relative;
    padding: 0px 5px;
    border-right: 1px solid #E00000;
    }

    #HouseMenuNavList li:last-child {
    border-right: 0;
    }

    The script:

    (function () {
    $$('#HouseMenuNavList li:last-child').each(function(el) {
    el.setStyle({borderRight: '0'});
    });
    })();

    A few points to note:

    1. Place the CSS in the head of the page (wrapped in style tags of course)
    2. Use Prototype 1.7.1 (again, in the head)
    3. Place the script (wrapped in script tags) in the body of the page, preferably right at the end, just before the closing body tag

    ReplyDelete