Dave Woods - Freelance Web Design Warwickshire

MouseOver Images Using CSS Sprites

It amazes me how many developers still resort to JavaScript to create a mouseover image effect especially when you consider that CSS can take care of this so easily. Within this tutorial, I’ll show how this can be achieved using a simple example with nothing more than CSS and a single image.

Example

Here’s a working example of this tutorial in action:

The Image

As promised, this example uses only a single image which contains both states.

HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<title>CSS Sprites</title>
<link rel="stylesheet" href="default.css"/>
</head>
<body>
<div id="container">
<a href="http://feeds.feedburner.com/DaveWoods">Subscribe RSS</a>
</div>
</body>
</html>

As you can see, the HTML is very simple. In practice you’d probably want to supply a class or place the link in a container which you can then target specifically but for this example, I’ve tried to keep things as simple as possible.

CSS

First, a bit of formating just to keep things consistent within the page.

* {
padding: 0;
margin: 0;
}
body {
font-family: "lucida sans", arial, verdana, helvetica, sans-serif;
font-size: 100%;
padding: 10px;
}

Next, we can add the image to the background of the link using the following bit of code.

a, a:link {
background-image: url(rss.gif);
width: 40px;
height: 40px;
text-indent: -999em;
display: block;
}

The image is actually 80px in height, so by specifying 40px, what we’re actually doing is only showing the top half of the image (i.e. the gray version of the icon).

The anchor is an inline element so width and height won’t have any effect  unless we add the display: block; rule to this style.

We’re also using the text-indent as an image replacement technique so that without CSS available, the user will get a text equivalent of the link.

The last thing we need to do, is to add the hover state which couldn’t really be any simpler.

a:hover {
background-position: 0 40px;
}

We’re already showing an icon of 40x40px so all we want to do on hover is shift the background image up by 40px to reveal the bottom section of the image and this is simply achieved by using the background-position.

Summary

There are various ways of achieving the effect of a hovering image but they usually involve using JavaScript which is completely unnecessary or alternatively, replace the image on hover which will cause a delay while the second image loads.

The advantage of this method is that it only requires one image and once the first image is displayed, the second image is already loaded with it and therefore it’s by far the fastest and easiest method to implement.

9 comments on “MouseOver Images Using CSS Sprites

  1. Dave Post author

    Hi duryodhan,

    Yes it would work but you’ll also find that the hover image only loads once it’s actually requested and therefore you get a blank gap displayed while the second image loads.

    You should also notice that the two images combined can usually be slightly smaller in file size so it also has that benefit along with fewer http requests so you can significantly speed up your site.

    Hope that helps.

  2. dr john

    One alternative if you use an unordered list for your menu is to use a different image (and colour) as the background for the list item and for the a:link. Then for a:hover, you simply apply no image to the link and a transparent background – no colour, so the image/colour shows through. Or if it is in a div with a background image, that can show through instead, removing the need for a background image for the list item. Or even a background image for the div, and a colour for the link, going to transparent on hover – see this example
    http://www.sky-web.net/taggartandwright/index.htm

  3. jackyboy

    This is ok, but i have a list of names and would like to have mouse roll over a name and picture pop up on side of name (in space i have saved for the pictures to show) also need to be able to click on name and go to another page. Name should not be a link. is this possible? Where would i find such a effect – how would i do it?

  4. Alan

    Dave,

    About the flicker when using background-image swapping. I have of course encountered the issue before. Oddly enough I have encountered a similar issue in IE when using this “sliding doors” method. For some reason, even though it was one actual image just being shifted on hover, IE6 would flicker out on me as if it was trying to reload the image and then slide it over. It didn’t happen all the time but I found a little piece of script that seems to cure the issue.

    function fixIE6flicker(fix) {
    try {
    document.execCommand("BackgroundImageCache", false, fix);
    } catch(err) { }
    }
    fixIE6flicker(true);

    It might also fix the issue with actually swapping the images instead of sliding them.

  5. Dave Post author

    Hi Alan, Do you mean that you’ve had problems with this method? If so, could you provide me with a link and I’ll be happy to take a look.

    Personally, I prefer not to use JavaScript unless completely neccesary and never for critical functionality unless there’s a fall back so I prefer to use the sliding method.

    It has another advantage in that using CSS sprites can reduce the filesize over saving each image individually.

  6. Jeff`

    Thank you for this. I was able to get it going on my site http://elka.dappledgrey.com but because there are three different images lined up (social media icons top right) I had to give each its own DIV and then use your code on each of the three DIVs. The hover portion I only had to include once.