Creating a horizontal menu using an unordered list and float

One of the ways you can create a horizontal menu is to use float. Probably not the simplest way but definitely a solid one that you can take and apply to a lot of other situations as well.

A nice and semantic way to do this is to use an unordered list. Let's start with the following markup:

<div class="menu">
    <ul>
        <li><a href="/">Home</a></li>
        <li><a href="/blog/">Blog</a></li>
        <li><a href="/about/">About</a></li>
        <li><a href="/contact/">Contact</a></li>
    </ul>
</div>

Remove the default styles

For a very clean start, remove the default margin, padding and list-style properties by adding the following rules to your stylesheet:

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

Set float on ul and li

To lay the elements horizontally, set float on the ul and li tags:

div.menu ul, div.menu li
{
    float: left;
}			

You may notice here that the definition above floats not only the li elements but also the ul elements. This is because when an element is floated, its parent becomes unaware of the child's height and collapses. The following illustrates what happens if you just float the li elements.

To tell the parent that the li elements are there, float the ul element as well. And here's what you'll get by doing this:

Make the links block elements

To make it easier to style the items of the menu, set display of the a tags to block.

div.menu li a
{
    display: block;
}

This means that the a tag will take up the entire width of the parent li tag. Also block elements allow you to set the width and the height unlike inline elements making it easier to style them.

Clear the side-effect of float

Although we've set float:left on the ul element, the wrapper element div.menu is still affected and has no height. Here's an illustration of what you've got so far (links aren't shown here to simplify the situation).

This may not look like a problem at first, but with this you can't basically give div.menu a background colour or image, or a border that nicely wraps around the menu.

A slightly tedious but easy way to solve this issue is to add an extra element after the ul element and clear the effect of float. The markup would be:

<div class="menu">
    <ul>
        <li><a href="/">Home</a></li>
        <li><a href="/blog/">Blog</a></li>
        <li><a href="/about/">About</a></li>
        <li><a href="/contact/">Contact</a></li>
    </ul>
    <div class="clear"></div>
</div>

And add this to your stylesheet:

div.menu div.clear
{
    clear: both;
}

For those who love semantic markup

If you love semantic markup and want no compromise for it, you can remove the clearing div and add this rather complex-looking piece of code to your stylesheet:

div.menu:after
{
    content: ".";
    clear: both;
    display: block;
    visibility: hidden;
    height: 0;
}

This should give you the same result.

Fix the double-margin float bug

To avoid the double margin float bug of IE6 and below, add this rule to your stylesheet:

div.menu li
{
    display: inline;
}

This does not affect other browsers so you can add this without any worries.

Hope this helps.

Rate This Posting

 

Comments

There are no comments made to this posting yet. Be the first to comment!

Leave a Comment

Your comment will be manually and carefully reviewed by the system administrator. Off-topic comments will be deleted without warning.

Some HTML is allowed. Line breaks are preserved.

If ticked Name, Email Address, and Url fields will be pre-filled the next time.

Related Blog Posts