It is popular to use ul and li elements float them and set them to width:auto in CSS in order to create a horizontal list of self-sizing boxes. These can easily be used to create horizontal navigation or a listing of tabs, and it works very well. However, there is one caveat; given the right mix of CSS this solution doesn’t work properly in IE 6.

To create this scenario, we can simply use something like the following:

<style type="text/css">
    ul {
        height: 30px;
        overflow: hidden;
    }
    ul li {
        float: left;
        width: auto;
    }
    ul li a {
        display: block;
        height: 30px;
    }
</style>
<ul>
    <li><a href="#">Link 1</a></li>
    <li><a href="#">Link 2</a></li>
</ul>

This will show the problem in IE 6 nicely. The problem is that IE 6 interprets this mix of CSS and decides that each li element should actually expand out to 100% width.

I’ll explain how to fix this issue and provide and example page so you can easily play around with the HTML and CSS yourself.

Fix #1

A quick way to tame the IE 6 beast is to give the offending element a width of 0. Counter to intuition, this won’t force the element to an infinitely-small width; rather, it will force IE 6 to automatically-size the width of the element. However, this has an immediate problem, all other browsers will see this width of 0 for what it really is and render nothing for that element since, well, it has a width of 0.

There are a few different ways to correct this:

  1. We can use a hack to introduce the width 0 command to IE 6 without having the other browsers take notice. This works and can be implemented by using _width:0 to specifically target IE 6. For example:
    #nav ul li {
        width: auto;
        _width: 0;
        float: left;
    }
  2. Since using a hack isn’t always preferable, another option is to selectively-load a CSS document that adds the IE 6-only behavior. In the HTML document, you first load the standard stylesheet followed by the IE 6-specific stylesheet:
    <link rel="stylesheet" href="/css/style.css" type="text/css" media="screen" />
    <!--[if lt IE 7]>
        <link rel="stylesheet" href="/css/lt-ie7.css" type="text/css" media="screen" />
    <![endif]-->

    In the IE 6 stylesheet, add the width:0 style:

    #nav ul li {
        width: 0;
    }
  3. We can use CSS selectors that are ignored by IE 6. This doesn’t use a hack and also avoids using a separate stylesheet.
    #nav ul li {
        width: 0;
        float: left;
    }
    #nav ul > li {
        width: auto;
    }

Each of these methods work nicely, however, after some additional testing, a new limitation becomes clear. For some reason, IE 6 now decides that only one word should be permitted in each box. Basically, it seems to word-wrap all additional words, effectively cutting them off. Thus the need for another fix.

Fix #2

The solution to preventing IE 6 from truncating each element is simple: prevent word wrapping. This is easily done using the white-space:nowrap CSS instruction.

Using the third example above, we can change it to the following to apply this next fix:

#nav ul li {
    width: 0;
    float: left;
    white-space: nowrap;
}
#nav ul > li {
    width: auto;
}

Example Page

I built an example page that shows what is actually occurring during each step of this process and shows how each fix improves the rendering in IE 6. The final example renders as it should.

Here is a screenshot that shows how it renders in IE 6:

ie-6-nav-issue

Example Rendering in IE 6

Did I help you?