Author: Justin Bezanson

Have you been told that using those fancy JavaScript navigation menus is bad for your search rankings or that you will lose some visitors that have JavaScript turned off? This is a decision that all web developers face at one time or another. Do you use the cool looking menu which may help clean up large menus or do you cater to the largest audience possible? That can be a tough choice sometimes. Well, now there is no need to choose. In this article I will show you how to create a drop down navigation menu that is XHTML 1.0 Strict, CSS valid, opens external links in a new window, and is JavaScript free.

 

Keeping Backwards Compatibility In Mind

To keep things in perspective, in order to be 100% XHTML 1.0 Strict and support older, non-compliant browsers, a small amount of JavaScript is required. If you do not wish to support IE6 or older and don’t mind switching to a XHTML 1.0 Transitional doctype then this can be accomplished with 100% pure CSS and no JavaScript.

 

The Structure of Our Menu

Lets take a look at the XHTML of the menu we will be working with. It is a simple menu with one external link that we will want to open in a new window and has a drop down one level deep.

<ul class="menu">
    <li><a href="home.html">Home</a></li>
    <li>
        <a href="about.html">About Us</a>
        <ul>
            <li><a href="company.html">Company</a></li>
            <li><a href="mission.html">Mission</a></li>
            <li><a href="careers.html">Careers</a></li>
        </ul>
    </li>
    <li>
        <a href="services.html">Services</a>
        <ul>
            <li><a href="webdesign.html">Web Design</a></li>
            <li><a href="webhosting.html">Web Hosting</a></li>
            <li><a href="consultation.html">Consultation</a></li>
            <li><a href="networking.html">Networking</a></li>
        </ul>
    </li>
    <li><a href="http://www.twitter.com/MadeUpCompany" rel="external">Twitter Page</a></li>
    <li><a href="contactus.html">Contact Us</a></li>
    <li class="last"></li>
</ul>

There are a couple things to take note of in the above code.

 

Using an Unordered List

The menu is layed out using a list. This is done because it is the proper semantic use of a list. A menu is just a list of links. Also this will help with search engine indexing. It will make it easier for search engines to crawl your page and understand the purpose of the code.

 

The rel Attribute

If you look at the link with the label “Twitter Page” you will notice this link has an attribute called rel with the value of external. All this does is mark that link so we can find it later when we set external links to be opened in a new window. If you do not want to use any Javascript in your menu and don’t mind using a Transitional doctype you can replace the rel=”external” with target=”_blank”. The target attribute is depreciated in XHTML and will not validate in a Strict doctype.

 

The Last List Item

You will notice that the last list item is empty and is assigned a class “last”. In order to position the menu items correctly they are “floated” (you’ll see what I mean in a bit). Floated items must be cleared when you are done with them in order to keep all the elements properly contained. The “last” class clears the floated items.

 

Opening External Links In A New Window

Now that we have our menu defined lets get to work on the functionality. First off when are going to take care of opening external links in a new window. As mentioned earlier, this uses JavaScript. If you chose the non-JavaScript method then you can skip to the next section.

var i; var anchors = document.getElementsByTagName('a');
for(i=0;i<anchors.length;i++) {
    if(anchors[i].rel == 'external') {
        anchors[i].onclick = function() {
            return !window.open(this.href);
        };
    }
}

The above code will fetch all the links on the page into an array. Then it will loop through the array looking for the rel attribute that is set to external. If it is found the script will assign an event handler to the onclick event of the link. The event handler will attempt to open the links url in a new window. If the new window fails to open, perhaps blocked by a popup blocker, then it will open the link in the same browser window. This way your users will not think the link is broken if it is blocked or fails to open the new window. If a user has JavaScript disabled the link will just open normally in the same window. Handling script failures in a graceful and functioanl way is very important for a positive user experience.

 

Get To The Good Part Already!

Well now that I have rambled on for a while, I will get to the meat of this article and show you what you came here for. The best way for me to explain how the CSS code works is to go through it one definition at a time. Note that I have added in some attributes to make the final result look prettier. I won’t bother explaining those bits.

ul.menu, ul.menu ul {
    padding: 0;
    margin: 0;
    list-style: none;
    border: 1px solid #b8b8b8;
    background: #f6f3f6;
    text-align: center;
}

This definition applies to the main unordered list element marked with class “menu” and all unordered lists within the main list. It is applying some formatting to make the menu look right. The padding, margin, and list-style settings remove white space around the list and remove the bullets for each list item.

ul.menu li {
    float: left;
    width: 8em;
}

This code is setting the width of all list items in the menu and floating them to the left. It is important to know that you cannot float an element unless it has a specific width applied to it.

ul.menu a {
    display: block;
    width: 8em;
    padding: 5px;
    font-size: 0.8em;
    font-weight: bold;
    color: #424242;
    text-decoration: none;
}

In this piece of code all anchor links are being given a width and set to a block display. By being a block display each link will automatically drop to the next line instead of appending to the same line as the link before. A width is set because a block level element has a width of 100% of it’s containing element by default which would throw our dimensions off.

ul.menu li ul {
    position: absolute;
    left: -999%;
    width: 8em;
    text-align: left;
}

This is where the magic of our CSS starts to work. Here we are setting the absolute position of all sub lists to move 999 percent to the left which will hide them from our view. We used -999 percent because IE7 doesn’t work if another unit of measure is used for some reason. We are also giving the list a width so it doesn’t take 100% of the available width.

ul.menu li:hover ul {
    left: auto;
}

This single setting makes it all happen. Notice that we are setting the sub list left position when a list item is hovered over. This will make the sub list show up at it’s original position before we hide it.

ul.menu li:hover ul {
    margin: 1px 0 0 -60px;
}

IE7 does support the li:hover selector but gets the position a bit wrong so in a separate stylesheet for IE7 and older, using conditional comments, I have included the above definition. All it does is move the sub menu down 1 pixel and to the left 60 pixels to where it should be. The :hover selector is not supported in Internet Explorer 6 or older. Next we’ll look at a bit of JavaScript code to make older browsers function properly. If you are not worried about supporting older browsers then you can skip over this part.

ul.menu li.over ul {
    left: auto;
    margin: 1px 0 0 -60px;
}
@if (@_jscript_version <= 5.6)
  // js code for IE6 or down
  var li = document.getElementsByTagName('li');
  for(i=0;i<li.length;i++) {
    li[i].onmouseover = function() {
        this.className += ' over';
    };
    li[i].onmouseout = function() {
        this.className = this.className.replace(' over','');
    };
  }
@else @*/
  // do nothing
/*@end @*/

The first bit of code is a definition for IE6 to get a round the lack of support for li:hover. It creates a class that defines sub lists when the parent list item has a class of ‘.over’.

The next bit of code is JavaScript. It is using the conditional comments built into JScript to detect IE6 (aka JScript 5.6 or older). We then assign event handlers to the onmouseover and onmouseout events that will place our ‘.over’ class on the list items to simulate the li:hover. Only a few lines of JavaScript so it’s not too bad.

Now on to the last one.

ul.menu li.last {
    float: none;
    clear: left;
}

Now, finally, we just clear the float of the list items so that they will be contained properly where ever they get placed on the page. Because Internet Explorer just doesn’t like to play nice I have included the definition below in our IE7 and older stylesheet to correct some alignment problems.

ul.menu li.last {
    display: inline;
}

 

Wrapping It Up

That’s it! You should have a functioning drop down menu that works with just CSS and a little JavaScript to support older browsers and validate to XHTML Strict. I have tested this code in IE6, IE7, IE8 beta 2, Chrome beta 1, Opera 9.51, and Firefox 2.0.0.17. If you find any mistakes just leave a comment and I’ll get things patched up. Hope you enjoy this!

You can also download a zip file of the source for this article from our Freebies page, grab our feed to have the password.

 

The author is Justin Bezanson from GeekDaily.

Tags :

16 Responses to “Spice Up Your Navigation With CSS Drop Down Menus”


  1. Travis

    Said on October 27, 2008 :

    Not seeing the password in the feed…

  2. stratosg

    Said on October 27, 2008 :

    that is a very nice and informative article mate. thx!

  3. logidude

    Said on October 28, 2008 :

    Live demos are always nice with these…

  4. Shahar Y

    Said on October 28, 2008 :

    @ Travis

    The password is in the bottom section of the feed.
    There Feed structure is:
    Title
    Ad
    Article
    Further Reading section
    Bottom section

  5. Dorian F

    Said on October 28, 2008 :

    Rather than having to have a separate class to do the clear, simply set the UL to overflow:hidden, this will ensure it contains all floated elements.

    Much easier than using clear because it can behave differently in IE/Firefox.

  6. espen

    Said on October 28, 2008 :

    Lovely article, but provide a live demo, por favor

  7. Dejan

    Said on October 28, 2008 :

    I can not access the freebies page with the password that is included in the feed :(

  8. Amit

    Said on October 28, 2008 :

    I bet you are using FireFox. It works only with IE.

    I think it is a FireFox bug.

    Sorry about that, I am trying constantly to find solutions for this.

    I hope I will find is soon

    Amit

  9. Travis

    Said on October 28, 2008 :

    “I bet you are using FireFox. It works only with IE.”

    That’s reassuring.

  10. Amit

    Said on October 28, 2008 :

    Saddly, you will have to take this matter with the WordPress development team…

  11. Chelsea

    Said on January 12, 2009 :

    This may be a stupid question, but do you know if you can add this Css html to a blog HTML? Do you know where I would add these codes in the html?
    Thanks for your time.

  12. ???????? ????? online

    Said on February 23, 2014 :

    ????? ????? ? ?????? ?????? ????? ???????
    ???? ?? ????? ????? ? ????????????? ??????? ? ????????
    ???? ?????? ?? 24 ???? ? ????
    ??????
    ? ???? ??? ???? ?? ????????
    ?????? ?? ????? ?????????? ???? ????, ? ????? ?????????? ?????? ?? 24 ????, ??????????? ?? ???? ????????????? ?????? ??? 399 ??,
    ????? ? ???????? ???????? , ?????? ? ??????? ??
    ?????????? ?? ???????,
    ???????????? ?? ?????? ??????, ?????? ?????? ?? ????? ???????? ??
    ???-??????? ??????, ??????????, ?????? ? ?????? ??????
    ?????? ?? ?????????????? ? ??????? ?? ??????, ??????? ??????????.

  13. Infinity 2 Global

    Said on March 4, 2014 :

    You actually make it appear really easy
    with your presentation but I in finding
    this matter to be actually something that I think I might never understand.
    It kind of feels too complicated and very large for me. I am
    having a look forward to your next post, I will try to get
    the hang of it!

3 Trackback(s)

  1. Mar 14, 2009: 11 MORE VISUAL STUDIO SHORTCUTS YOU SHOULD KNOW | Dev102.com
  2. Apr 28, 2009: How to Create A JQuery Plugin | Dev102.com
  3. Dec 19, 2011: More 11 Visual Studio Shortcuts You Should Know » ?????? ???????? ????? ??? ???

Post a Comment