Write-up: fixing the IE6 CSS background image flicker bug

Creating a graphical navigation menu with rollovers, in the modern fashion.

This means that while using images and dynamic behaviour to enhance appearance, we can use CSS-only image replacement (Doug Bowman’s overview) and rollovers (Pixy’s original article) for the sake of accessibility and SEO and to avoid depending on JavaScript that might be unavailable.

The problem: if its cache is set to check “Every visit to the page”, Internet Explorer 6 will display an ugly flicker when you hover over a link using the dynamic image backgrounds required in this method.

And so, the fix: add the following lines to an .htaccess file (or to httpd.conf) on the server:

ExpiresActive On
ExpiresByType image/gif A2592000
ExpiresByType image/jpeg A2592000
ExpiresByType image/png A2592000

Simple, right? However, since there are several suggested methods for fixing this and little consensus on which is best, I spent several hours the other day tracking down the definitive answer. So I decided to write this up in case it helps anyone else looking for a solution.

Dan Popa devotes a whole website to suggesting a proprietary MSHTML command as a fix; Cristi Balan proposes further refinements using JavaScript and CSS.

Ryan Carver’s article advises “double-buffering” the background image in your CSS.

Dean Edwards’ solution is the one I eventually chose, or rather the stripped-down version Ryan mentions.

The other methods just had too many drawbacks: despite being a clever find, the MSHTML command only works in IE6 SP1, and depends on JavaScript, amongst other things. The double image fix seems kludgy and requires extra markup and CSS bloat. So why not the Apache method? I’m guessing a lot of confusion was caused by client-side developers’ not being allowed access to change server settings—or maybe just a preference for client-side-only fixes, even though editing an .htaccess file is the simplest answer to the problem and has none of the issues created by other methods. This article at Adobe doesn’t even mention the server method, despite aspiring to provide an overview of the issue.

The only reservation I have is that Ryan couldn’t get it to work, but so far I can’t see any problems and haven’t read anywhere else of issues.

I used the Firefox Web Developer Extension to check my server was setting the expires and cache-control headers OK. Since there were no vary headers being sent, I could leave aside the force-no-vary directive that Dean Edwards mentions. The Apache mod_expires documentation came in useful for checking its specifics.