The IE6 Randomly Bulleted Menu Bug


This article was written in 2004, long before I had learned of IE6’s mysterious and vexing hasLayout property. The disappearing bullet backgrounds can be fixed without increasing the selector’s specificity by invoking hasLayout on the list items.

There are a few ways to trigger Layout in IE, but the preferred method nowadays is the IE-proprietary zoom property. Applying zoom: 1; to the li element invokes hasLayout with no other effects, apart from the effects inherent in triggering Layout. Zoom is a feature in versions of IE that allows authors (or users) to resize the contents of an element, but a value of 1 simply instructs IE to zoom the element to its regular size, hence no visible effect. It’s non-standard property that other browsers will ignore, but it’s best to deliver the fix to IE alone via conditional comments. IE8 and higher have at last done away with this screwball hasLayout voodoo.

As I’ve become increasingly comfortable with standards-based CSS web design, I’ve become increasingly annoyed with the Microsoft Internet Explorer browser. It just does so many odd little things with your CSS, but it’s the most pervasive browser in the world so you simply can’t ignore it. I’ve encountered one such annoyance in some recent design work, but in all my googling I haven’t found any other resource that specifically addresses it. Maybe it’s a known bug, but I decided to do this little writeup and share it with the world anyway. OK, maybe not the world, but at least the three or so people who read this website.

When using unordered lists for a navigation menu, combined with a custom graphic bullet for other lists, the bullet image sometimes appears in the menu list in spite of the menu list having its own specific style definitions which emphatically tell it not to use a bullet. Read on for analysis and the simple workaround.

A Cascading Style Sheet is a set of rules telling the browser how to display various elements in the page markup. But some browsers have trouble understanding those rules, if they can read them at all. For example, you can say to the browser “This element should have 5 pixels of padding on each side” and smart, obedient browsers will do so. But some browsers, specifically IE5/Win in the example, will answer “but that element isn’t block-level, so I’m going to ignore your instructions and display those elements with no padding at all.” It’s this kind of stubborn disobedience that has made Internet Explorer the bane of modern web designers. But on to the matter of bullets and menus.

The Problem

I recently decided to use a common unordered list to mark up a left-side navigation for a website, and then use CSS to style that list the way I wanted. Elsewhere in the site, we were using regular bulleted lists in our content, and I wanted those bulleted lists to have a nifty graphic bullet instead of the boring default dot. The left navigation menu is contained in a div with the unique id “leftnav”, so subsequent style rules specific to the left nav can key off that id. Here’s the relevant CSS:

ul li { list-style: disc url(bullet.gif); }
#leftnav ul li { list-style: none; }

That snippet instructs the browser to apply a graphic bullet to each list item within an unordered list wherever it occurs on the page, except if it occurs in an element with id=”leftnav”, in which case it should have no list style at all. Smart browsers understand this and render each list properly. But not IE6 for Windows. IE6 frequently and sporadically shows the bullet on the menu lists as well, at least when the page initially loads. The left nav list items consist of blocked links, each with a :hover style to simulate a highlighted button. As soon as you mouse over one of the menu items, the :hover style is invoked, whereupon IE6 snaps to attention and vanquishes the bullets, as if to say “Durr now I get it, it’s one of THOSE lists.”

I argued with this bug off and on for a few weeks, assuming it was some error in my leftnav list stylings, before finally realizing that the nav list was fine, it was the general list style causing the problems. Of course, the most immediately obvious solution is to remove the custom bullet, but I really liked those fancy dots and wanted to keep them. So now (drumroll) the workaround. I call it a workaround since it’s not really a solution. A real solution would be to fix the bug in IE so it obeys the styles it’s given, and that might even happen in the next service pack update, who knows. But anyway, (drumroll) the workaround:

The Workaround

This is a problem with specificity. I’m using contextual selectors to specify which list items are assigned which style attributes. But the general list style definition lacks the specific context the left nav lists enjoy, and IE6 gets confused. So we need to give it clearer instructions. This requires all non-leftnav lists (the ones we want to have the fancy dots) to reside in some specified parent element. Luckily the site I was working on when I discovered this bug was already placing all the page content inside an element with id=”content”, giving me another unique identifyer to refer to. The revised CSS:

#content ul li { list-style: disc url(bullet.gif); }
#leftnav ul li { list-style: none; }

This tells the browser “if a list is inside something called ‘content’ use a fancy bullet, and if a list is inside something called ‘leftnav’ don’t use a bullet at all.” It’s not really a bad idea anyway, even for compliant browsers. However, this does mean that any lists that are not held within “content” will use the browser’s plain default dots. It’s a small compromise, but it doesn’t really hurt too much.