CSS Image Swap

March 10, 2006

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:

logo

Now, the code:

<div class="nav">
<a href="#">
<img src="logo.gif" width="187" height="136" alt="" />
</a>
</div>

And the CSS to go along with it:

div.nav {
height: 187px;
width: 136px;
margin:0;
padding:0;
background-image:url("logo-red.gif");
}

div.nav a, div.nav a:link, div.nav a:visited {
display:block;
}

div.nav img {
width:100%;
height:100%;
border:0;
}

div.nav a:hover img {
visibility:hidden;
}

You will see that it’s pretty basic – setting width and height attributes for the image, and basically just telling the browser “when someone hovers over the image, make it disappear” – and it simply reveals the background image for the div – your “hover” state.

This, of course, will work in all manner of ways. If you have a navigational list, simply replace the <div class="nav"> with <li class="nav">. 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):

<!--[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. (that last one has a slight padding glitch, which is a result of my global stylesheet – easily fixed, if I really felt like dealing with it…but the point is, the rollover effect does work perfectly there.)
Tested on Mac OSX Leopard: FF3, Safari 3.2.1, Camino 1.6.6, Opera 9.63.

View Comments

Sorry, comments are now closed on this post. You may thank the spammers for that one. But if you have any questions, please feel free to email me and ask - maybe it'll make for a good update in a future post. :)