Minimize Flickering CSS Background Images in IE6

Internet Explorer 6 for Windows is a sore spot for many users of CSS. Besides its countless rendering problems, it has the annoying habit of causing background-image styled elements to flicker when moused over. This article will cover a few things I've found that will eliminate that flicker.

Overview

Flickering causes more problems than just annoying the user (not to mention the designer!). The reason the image flickers is that every time you mouse over, the image is re-requested from the server. This means increased bandwidth usage. Also, the slower the user's connection, the longer that will take and the more intrusive it will be.

The cause of flickering is choosing "Every visit to page" in Tools » Internet Options... » Temporary Internet Files » Settings...

Selecting anything other than "Every visit to page" will fix all flickering. Fortunately, the means that the flicker problem plagues developers far more than your common user. However, there are a few ways to avoid it even with this setting.

Clarification

By flicker, I mean where an image disappears for a short time when the mouse is moved over or out of the it. From time to time you will also see a distortion where some part of the page will show behind the image or garbage will be drawn in its place on mouse over, but this seems to be a separate issue that isn't consistently reproducable.

Update - 06/03/2004

Dean Edwards may have found the solution. Read more, but it boils down to putting the following into your .htaccess file.

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

Update - 04/08/2004

Dan Cederholm links to PGA.com's new tabs. They don't flicker. Here's what I learned from them.

Simply combine the Pixy No Preload method with a double-buffered background (image on containing element and anchor tag). Like this:

This seems very very similar to Pixy's workaround but it never worked for me before.

Amazingly this method avoids both flicker and distortion. Enjoy.

/* using image replacement for all nav items */
#nav dt a {
  display: block;
  padding-top: 23px; height: 0px !important;
  height /**/: 23px; overflow: hidden;
}

/* double buffer the image by placing it on BOTH the containing element and the anchor */
#nav dt.share {
  width: 164px;
  background-image: url(/images/home_share.gif);
}
#nav dt.share a {
  background-image: url(/images/home_share.gif);
}

/* using the pixy double image method, so move the image around on :hover */
/* Note: this is one of the causes of flicker, but we don't see it because it's double-buffered */
#nav dt dt.share a:hover {
  background-position: 0 23px;
}
  

Examples

All examples start with the following CSS to create a simple image replacement. From there we will add or modify properties to create or remove the flicker.

Please use IE6 on Windows with a cache setting of "Every visit to page" in order to see the examples work.

a {
  display: block;
  width: 200px;
  height: 50px;
  text-indent: -100em;
  background-image: url(square.gif);
}  
  

square.gif is just a 50x50 pixel square image with a circle in the middle:

the test image

Cause: background properties

An image will flicker if any of the following properties are set on the element (directly or inherited).

  • background-color: any value but transparent
  • background-repeat: any value but repeat
  • background-position: any value

Examples

Link Text This image doesn't flicker.

a {
  background-color: #f00;
}  
  

Link Text This image flickers because background-color is not transparent.

a {
  background-repeat: no-repeat;
}  
  

Link Text This image flickers because a background-repeat is not repeat.

a {
  background-position: 0 0;
}  
  

Link Text This image flickers because background-position is set (even to 0 0 or top left.)

Cause: Pixel area of element

The area of an element with a background-image must be at least 2500 pixels.

Examples

a {
  width: 50px;
  height: 50px;
}  
  

Link Text This does not flicker because 50x50 = 2500

a {
  width: 49px;
  height: 50px;
}  
  

Link Text This image flickers because 49x50 = 2450

a {
  width: 49px;
  height: 51px;
}  
  

Link Text This image flickers because 49x51 = 2499

a {
  width: 49px;
  height: 52px;
}  
  

Link Text This does not flicker because 49x52 = 2548

Cause: Transparent GIF's

Transparent .gif's will always flicker.

Examples

Link Text This image flickers because the background-image is a transparent .gif

Other Workarounds

If you just can't avoid using one of the background properties, have to use a small images or transparent .gif's there are a couple ways to hide the flicker.

Duplicate the image

Put the background-image in the surrounding element as well as the anchor tag. This way, even if the image flickers you'll have the same thing behind it and you won't be able to tell. This is an easy fix for the common navigation list.

Examples

li a {
  background-image: url(square.gif);
}
  
<ul>
  <li><a href="#">Nav Item 1</a></li>
  <li><a href="#">Nav Item 2</a></li>
</ul>
  

Flickers because image is only on the anchor and size is less than 2500.

li,
li a {
  background-image: url(square.gif);
}
  
<ul>
  <li><a href="#">Nav Item 1</a></li>
  <li><a href="#">Nav Item 2</a></li>
</ul>
  

No flicker because image is on list item and anchor. Note that this only makes sense this when doing a :hover image swap, otherwise it would be better just to put the image on the outer element.

Variations

Pixy's No Preload Rollovers used to be my favorite way to do image swapping. Unfortunately, they are doomed to cause flicker because the whole idea is to use background-position. A workaround is suggested where you put the hover state image in the outer element, then on :hover of the inner element set background-image: none;.

Server Settings

Changing the server's headers can supposedly fix flicker. I have not been successful with this technique, however. Please let me know if it works for you.

Conclusion

Hopefully this will give designers a few more tricks to avoid flickering images in IE6. Thanks to Dave Shea for help testing, and for interviewing me at WaSP which is why I took another look at this problem to begin with.