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:
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 buttransparentbackground-repeat: any value butrepeatbackground-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.