How to use CSS for Flickerless Image Replacement

By Stu Nicholls

Step 5

Adding the initial images

Now it starts to get interesting (and more involved), so make sure you understand this step before continuing.

In order to stop the flicker in Internet Explorer we need to ensure that there is an image on screen at all times. This may sound obvious, but the answer is not.

My answer is not to hold the initial image in the link tag <a>, but to put it as a background image in the list tag <li>.

Here, each list tag <li> is given a unique class which can be used to style the background color and image. To do this, add the following lines to your CSS:

/* Step 5 - Adding the initial images */
#menu li.list1 {background:transparent url(/img/2008/06/gainsborough_s.jpg);}
#menu li.list2 {background:transparent url(/img/2008/06/matisse_s.jpg);}
#menu li.list3 {background:transparent url(/img/2008/06/monet_s.jpg);}
#menu li.list4 {background:transparent url(/img/2008/06/renoir_s.jpg);}
#menu li.list5 {background:transparent url(/img/2008/06/picasso_s.jpg);}

Remember that if you are using an external css file the path to the images is taken from the CSS file not the (X)HTML file.

The list now has partial images:

Example three

You will notice that the images are not fully shown and the link text is still visible. Don't worry. The size will be defined later. Just be aware that the background images are in place.

Step 6

Styling the link tags

Even more interesting things happen when we style the link tags <a>.

The first thing is to apply a general style to all the links. The critical styling is the height of zero! This is used with an overflow:hidden; style to stop the link text from being displayed, but if it's got no height then how can we have a background image? Well, with a bit of lateral thinking we can add a top padding equal to the height of the image, which will ensure that the text remains invisible but gives our link an area in which to display the background.

The general link styling is as follows:

/* Step 6 - General link styling */
#menu a {display:block; width:83px; height:0; padding-top:128px; color:#000; overflow:hidden;}
/* hack for older versions of IE with incorrect box model */
* html #menu a:link, * html #menu a:visited {height:128px; he\ight:0;}

And the result looks like this:

Example four

Notice that I have added a hack for earlier versions of Internet Explorer to correctly define the height of the links.

Also notice that the size of the link is taken up by the list tag <li> and the background images are now displayed correctly. The link tags have a transparent background color that allows the list images to be seen and the link text has gone.

Step 7

Separating the images

With the images next to each other it's a little unclear where one finishes and the next begins, so I've added a gap between them. This is easily achieved by adding a right margin to the list tag <li>, so change the <li> style as follows.

/* Step 7 - Separating the images */
#menu li {float:left; margin-right:1px;}

And the result looks like this:

Example five

Step 8

Adding the :hover images

We're almost finished. All we need to do is add the hover state images to each of the link tags <a>. We have given each link a unique id so that we can target each one separately. We could just style the background images to be loaded 'on hover,' but it would be more user friendly to preload the images before the visitor hovered over the links thus creating an instant change.

This is possible for those browsers that cache background images that are not initially displayed.

My method is to add the background image to the un-hovered link and to move the background image position out of view.

This is achieved using the following additional CSS link styling:

/* Step 8 - Adding the hover images */
#menu a#item1 {background:transparent url(/img/2008/06/gainsborough_c.jpg) -130px -90px no-repeat;}
#menu a#item2 {background:transparent url(/img/2008/06/matisse_c.jpg) -130px -90px no-repeat;}
#menu a#item3 {background:transparent url(/img/2008/06/monet_c.jpg) -130px -90px no-repeat;}
#menu a#item4 {background:transparent url(/img/2008/06/renoir_c.jpg) -130px -90px no-repeat;}
#menu a#item5 {background:transparent url(/img/2008/06/picasso_c.jpg) -130px -90px no-repeat;}

You will see that the hover images are not displayed when the mouse is hovered over the links. This is because the :hover state has not yet been defined.

The background color needs to be transparent to allow the list images to show through and the image position need to be given at least one negative (or positive) value that is larger than the image size. 'no-repeat' is used to ensure that the image will be displayed only once.

The list now looks like this:

Example six

Step 9

Defining the :hover style

Finally, we get to the bit that does all the work - the :hover style. This is a straightforward link style that moves the background images into place at the top left of each link and is styled by adding the following to your CSS:

/* Step 9 - Adding the :hover style */
#menu a#item1:hover {background-position:0 0; z-index:50;}
#menu a#item2:hover {background-position:0 0; z-index:50;}
#menu a#item3:hover {background-position:0 0; z-index:50;}
#menu a#item4:hover {background-position:0 0; z-index:50;}
#menu a#item5:hover {background-position:0 0; z-index:50;}
* html #menu a:hover {height:128px; he\ight:0;}

The z-index is needed to make sure that the link background is displayed on top of the list background. Without it, older versions of Internet Explorer will not display the hover image. Again, I have added the box model hack for older versions of Internet Explorer.

Here's the working list:

Example seven

Step 10

Lastly - clearing the float

Because this list uses 'float:left,' you will need to clear this to make sure that the page flow will continue as required. There are many ways of doing this but the easiest is to define the height and width of the containing div #menu. This needs to be larger than the total size of the list images and in my case I have used width=430px and height=130px. To modify the CSS, add the following style values:

/* Step 10 - Clearing the float */
#menu {display:block; width:430px; height:130px;}

And we FINALLY end up with this:

Example eight

And that, as they say, is it.

Flickering menus are a thing of the past!

About the Author

Stu's website documents his attempts at understanding and exploring the possibilities of CSS. From standard navigation links to his more bizarre experimental techniques. All of his examples are produced with JUST CSS--no javascript, or any other language, has been used in any of the examples. [Editor's note: Prepare to be amazed!] http://www.stunicholls.myby.co.uk/

This article originally appeared on WebReference.com.

Page 2 of 2

Previous Page
1 2

  • Web Development Newsletter Signup

    Invalid email
    You have successfuly registered to our newsletter.
Thanks for your registration, follow us on our social networks to keep up-to-date