CSS Image Swap
Image Swaps are most commonly used for navigation. usually, they rely on javascript for anything more complex than a background color. But you can do it just using CSS!
Now, we come across a trick I ran into this morning. Someone had asked about a CSS-based rollover image swap for a site.
You’ve seen these rollovers before – usually implementing javascript (I believe Dreamweaver even has this kind of function built in? I don’t know for sure – I don’t use it!) – usually for navigational purposes. Basically, the end user comes to the site, hovers over your link and the image swaps out to something that “highlights” the users choice.
The thing is, when you use CSS for this type of thing, there has to be something between the <a> and </a> tags to trigger the image swap. Simply setting the CSS to swap out the background on hover seems like it should work, but it won’t – simply because there’s nothing in the HTML to tell the browser that it is being hovered over.
So, how do we get around this?
Easy!
This is one of those things in CSS that requires you to “think outside the box”. You’re so used to using javascript and thinking of it as an “image swap” – meaning one image simply replaces the other on hover.
With the CSS-only version, you need to think of it more as a “disappearing act”.
So, let’s get on with the example, so you can implement it, javascript-free, on your site!
First, the example:
Now, the code:
1 2 3 |
<div class="nav">
<a href="#"><img src="logo.gif" width="187" height="136" alt="" /></a>
</div>
|
And the CSS to go along with it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
.nav {
margin:0;
padding:0;
background:url("images/tutorial_images/logo-red.gif") no-repeat;
}
.nav a, .nav a:link, .nav a:visited {
display:block;
width: 187px;
height: 136px;
}
.nav a:hover img {
visibility:hidden;
}
|
You will see that it’s pretty basic – setting width and height attributes for the link, and basically just telling the browser “when someone hovers over the image, make it disappear” – and it simply reveals the background image for the link – your “hover” state.
This, of course, will work in all manner of ways. If you have a navigational list, simply wrap the anchor tags with list items (<li>). You will also have to separate them – if you’re using 12 different images (6 images for the “on” state, and 6 for “off” – 2 images for each link), you’ll have to set 6 different classes for each image, since none will have the same images representing them.
So yes, it does increase your CSS filesize. But, if you’re looking for a certain type of display, and you (or your client) desires a particular font, size and color for certain elements on the site, this is an excellent alternative to using a javascript image replacement. An added bonus – users who have javascript turned off in their browsers will still see the rollover effect.
Now, keep in mind, you have to deal with IE. (yeah, I bet you weren’t expecting that!) Well, the thing with IE is, it has problems caching background images. So if you move your mouse over the above stuff in IE, it’ll change as expected – but if you move ever so slightly, you’re going to see the blue flash back over. So as you slowly move your mouse across the image, it’ll flicker “redblueredblueredblue” – which is as annoying as hell.
This is actually easy to fix. In your header (or if you’re using a conditional comment to pull in an external stylesheet for IE, simply add this line to the bottom of the IE-specific stylesheet):
1 2 3 4 5 6 |
<!--[if lte IE 6]>
<style type=text/css">
div.nav {background-repeat:no-repeat;}
div.nav a:hover {visibility:visible;}
</style>
<![endif]-->
|
You must be sure that, for IE, that the “background-position” attribute is NOT set. If you set a background-position for the div, then the flicker will reappear.
Otherwise, you’re set! Enjoy your javascript-free rollovers.
Tested on Windows XP: FF 1.0.7, FF2, FF3, IE 8, IE 7, IE 6.0, IE 5.5, IE 5.0, Opera 8 and Netscape 7.
Tested on Mac OSX Tiger: Safari 2.0, Mozilla Firefox 1.0.6, and IE 5.2.
Tested on Mac OSX Leopard: FF3, Safari 3.2.1, Camino 1.6.6, Opera 9.63.
Note: January 2012 – updated code.

Comments
Is there a way to use a 3 image sprite. I want to show one image, have it change to a second when you hover, and a third when you click. Can this be done?
John April 25, 2012 at 6:31 pmYou should. It’s CSS, so you’d just have to edit it a bit to fit your needs. If you want the same image to appear for both the hover and active states (for the span *and* the link) it would require a different bit of CSS for the span, but if it’s just for the link, using a sprite is easy. You just need to mess with the visibility and the background-position state in your CSS to fit your needs.
Shelly April 26, 2012 at 8:05 amHow would you separate for multiple sets of images, as you mentioned above?
Jon July 8, 2012 at 7:40 amHow would I use it for other links in my navigation bar?
Michael Malab September 14, 2012 at 11:09 amCan you elaborate? I’m not sure what you mean by “other links” in your navigation bar?
If I had to guess, all I could say is you’d have to add a class to your nav links (using WP Nav Menus) when you’re making your menu, and style it that way. but other than that, I’m not sure what you’re asking?
Shelly September 19, 2012 at 10:33 amThere are a bunch of images missing from this page, so I can’t follow everything you’ve set forth.
kimi wei September 25, 2012 at 9:36 amSo sorry… I accidentally deactivated my code plugin! it was parsing the PHP instead of showing it! Fixed now
Shelly September 27, 2012 at 12:17 pmFunny thing is I get the flicker effect/bug you mentioned in Win/Firefox 16.0.2, too.
Christian Scholz-Flöter December 13, 2012 at 6:31 am