CSS Horizontal Menu

26 Oct 2011 by Shingo Tamura

One of the ways you can create a horizontal menu is to use float. It's probably not the simplest way, but is definitely a solid one that is adaptable and can be applied to a lot of other situations as well.

A neat, 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. Here's an example 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>

I also recommend that you 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.

About the Author

Shingo Tamura photo

Shingo Tamura is a web developer based in New Zealand with 8+ years of experience in web development. Shingo is capable of dealing with a wide range of web or non-web technologies, and has a passion for HTML, CSS, JavaScript and Web Usability.

Follow him on Twitter at shingokko.

Rate This Posting

 
blog comments powered by Disqus

Related Blog Posts