Show/Hide Contents

Mark Newhouse wrote an A List Apart article, “Taming Lists,” and Max Design’s Listamatic2 featured a nested version of one styled list in that article.  Unfortunately, that list was too wide in IE6 Standards-Compliant mode.  Now, that list has been adapted for IE6 Standards-Compliant mode by Alan Hogan.

Standards-Compliant Mode in IE Now Enjoys the Taming list!

see below: HTML | CSS

This page is XHTML1 transitional, in Internet Explorer Standards-Compliant mode (XML prolog missing), and appears the correct width (as in Gecko browsers).

Explanation:

How is this possible? What have I done that hasn’t been done before? It’s startling simple: I defined (horizontal) padding and borders with em-values instead of pixels, freeing me to define a (link) width using ems instead of the traditional “100%” (which is a. what messes up IE in Standards mode and b. necessary to get IE to consider the whole a block clickable and hoverable as opposed to the text only).

It still works terrifically in good little browsers such as Firefox. We do not even have to “clean up” after specific code for IE, because not a single CSS “hack” was used!

Before adjusting to this method, we begin with styles like those in “Taming Lists.” (We start with an unordered list - see HTML below.) These styles format the list to look almost like a table with cells as links.

#navcontainer {
  width: 12em;
  border-right: 1px solid #000;
  padding: 0px;
  margin-bottom: 1em;
  font-family: Verdana, Lucida, Geneva, Helvetica, Arial, sans-serif;
  background-color: #90bade;
  color: #333;
}
#navcontainer ul {
  list-style: none;
  margin: 0px;
  padding: 0px;
  border: none;
}
#navcontainer li {
  border-bottom: 1px solid #90bade;
  margin: 0;
} 

The first step is to decide how many ems wide you would like your list. Here, I chose twelve (12em). In IE Quirks mode, that would have been written something like this:

#navlist li a {
  width: 12em;
}

Or like this:

#navlist {
  width: 12em;
}
#navlist li a {
  width: 100%; /*Otherwise, IE wouldn't let us hover on the box, just link text*/
}

But in this new approach, we do it differently. We can define the list (ul) to 12em, or its container, but we don't set the width on each a yet.

Step two is to decide on padding for each a element. Top and bottom paddings do not matter much - here we use 5px for first-level items, 4px for second-level items, 3px for third-level items. It’s the left and right padding values that matter. For all level items, we use .5em. As for left padding, we vary it to get that “indented” look. Values: .5em for first-level items, 1.3em for second-level items, 1.9 for third-level items. (Remember, padding: shorthand is top right bottom left.) So our CSS is looking like this:

#navcontainer li a {
  display: block;
  padding: 6px .5em 6px .5em;
}
#navcontainer li li a {
  padding: 4px .5em 4px 1.3em;
}
#navcontainer li li li a {
  padding: 3px .5em 3px 1.9em;
}

Step three: Define borders in ems. (Again, top and bottom values do not matter much; here we have none.) For all three levels, we use .7em solid borders.

#navcontainer li a {
  display: block;
  padding: 6px .5em 6px .5em;
  border-left: .7em solid #1958b7;
  border-right: .7em solid #508fc4;
}
#navcontainer li li a {
  padding: 4px .5em 4px 1.3em;
  /*Inherits borders from #navcontainer li a*/
}
#navcontainer li li li a {
  padding: 3px .5em 3px 1.9em;
}

Step four (and this is pretty much it!): For each link level, subtract left and right padding and border widths from our total desired width (12em, remember?). Use this value as the width. This is only possible because our horizontal padding and borders are em-based. Then, throw in some code to style the background color and jazz like that, and a :hover pseudoclass for the mouseover effect. We end up like this:

#navcontainer li a {
  display: block;
  padding: 6px .5em 6px .5em;
  border-left: .7em solid #1958b7;
  border-right: .7em solid #508fc4;
  background-color: #2175bc;
  color: #fff;
  text-decoration: none;
  width: 9.6em;
}
#navcontainer li li a {
  padding: 4px .5em 4px 1.3em;
  background-color: #5ba3e0;
  width: 8.8em;
}
#navcontainer li li li a {
  padding: 3px .5em 3px 1.9em;
  background-color: #73b2e8;
  width: 8.2em;
}
#navcontainer li a:hover {
  border-left-color: #1c64d1;
  border-right-color: #5ba3e0;
  background-color: #2586d7;
}

Because IE6 Standards-Compliant mode uses the correct box model, and we did not “fudge” or hack anything for IE, we do not need to fix anything for modern browsers such as Opera, Firefox, and Safari. Therefore the following line was therefore unnecessary and removed.

html>body #navcontainer li a { width: auto; }

HTML:

  <div id="navcontainer">
    <ul id="navlist">
    <li id="active"><a href="#" id="current">Item one</a>
      <ul id="subnavlist">
        <li><a href="#" id="subcurrent">Subitem one</a></li>
        <li id="subactive"><a href="#">Subitem two</a>
          <ul id="subsubnavlist">
            <li><a href="#">Sub-subitem One</a></li>
            <li><a href="#" id="subsubactive">And Two</a></li>
          </ul>
        </li>
        <li><a href="#">Subitem three</a></li>
        <li><a href="#">Subitem four</a></li>
      </ul>  
    </li>
    <li><a href="#">Item two</a></li>
    <li><a href="#">Item three</a></li>
    <li><a href="#">Item four</a></li>
    </ul>
  </div>

Final CSS:

#navcontainer {
  width: 12em;
  border-right: 1px solid #000;
  padding: 0px;
  margin-bottom: 1em;
  font-family: Verdana, Lucida, Geneva, Helvetica, Arial, sans-serif;
  background-color: #90bade;
  color: #333;
}
#navcontainer ul {
  list-style: none;
  margin: 0px;
  padding: 0px;
  border: none;
}
#navcontainer li {
  border-bottom: 1px solid #90bade;
  margin: 0;
}
#navcontainer li a {
  display: block;
  padding: 6px .5em 6px .5em;
  border-left: .7em solid #1958b7;
  border-right: .7em solid #508fc4;
  background-color: #2175bc;
  color: #fff;
  text-decoration: none;
  width: 9.6em;
}
#navcontainer li a:hover {
  border-left-color: #1c64d1;
  border-right-color: #5ba3e0;
  background-color: #2586d7;
  color: #fff;
}
#navcontainer li li {
  border-top: 1px solid #90bade;
  border-bottom: 0;
  margin: 0;
}
#navcontainer li li a {
  padding: 4px .5em 4px 1.3em;
  background-color: #5ba3e0;
  width: 8.8em;
}
#navcontainer li li li a {
  padding: 3px .5em 3px 1.9em;
  background-color: #73b2e8;
  width: 8.2em;
}

Notes:

Screenshots of this page in various browsers and OSs

Tested & Works In: IE6/WinXP Standards-Compliant mode, Firefox 1.0.5, Opera 7/Mac & 7.5/Win & 6/Mac, Mozilla 1.7.5/Win and 1.6/Mac, Konqueror 3.0.5, Safari 1.2

Not Tested: Everything else

Not Nice In: IE6/WinXP Quirks mode (jagged & too thin), IE4/5/5.5 (IE5.0 does not seem to show the nav at all)

An unintentional, but welcome, benefit of my approach is the way the borders and padding scale with the font at extreme font sizes (during user text zooming). (Try it.) Note that the effect is horizontal only, because I left vertical padding and border values defined in pixels. You may change them to em values too, but be forewarned: Spacings may appear somewhat random due to rounding.

I have also added a third level, because I can and because it is useful.

I also suggest removing the containing div and styling the first ul if you really want the black line and/or a background color for the list. Why? Because an unsightly (but not catastrophic) gap between the wrapping div and the first ul (on the right) appears at large font sizes in IE.

For a discussion of this list, a Quirks-mode compatible version, and a substantially different (no side borders) version for IE/Standards Compliant, read Taming the "Taming lists" model by Russ Weakley.

Issues:

Does not work in IE6 Quirks mode. For that, use this version.

In IE, Safari, and Opera 7.5, there may be a 1px gap to the right of the subitem and/or “sub-subitem” items. Gecko browsers are not affected.

In IE6, text zooming does not work out favorably, apparently because IE6 doesn’t calculates em-based border widths based on the Normal font size, but calculates box widths in the expected manner. Gecko browsers ace this test.

I suggest removing the container div and styling the first UL instead. Why didn’t I? To keep the code as close to the original as possible.

Comments? Mistakes? Fixes?

If I goofed, even grammatically, send me a note. If you have comments, send me a note. If you improved upon this approach, send me a note! Contact me at taming - list at pixels and pages dot com.

Alan Hogan, Pixels & Pages July 2005