I noticed that Smashing Magazine recently posted a pretty epic article about CSS sprites. I've been using this technique for quite a while now, but its still surprises me how many sites (even relatively new ones) still go down the single image rollover state, often using that bloated chunk of javascript code from Dreamweaver that has been around since the dawn of time. You know the one - with the MM_preloadImages() and MM_swapImage() restore functions.
Not a CSS Sprite
I first knew of CSS Sprites as the 'sliding doors' CSS technique posted on A List Apart and there was an article in 2004 that put it forward as well. I like sprites, sprites are cool. Not just because they sound like something you should bump into at Halloween, but because they remind me of designing 8-bit graphics on my ZX Spectrum. Before anybody have even thought of Photoshop I used to design small bitmap images on graph paper then figure out the binary so I could make my custom 8-pixel square space invader boing around the screen in one of the random mini-games I used to make when I was a kid (I've never been one for football) It was all the rage in Your Sinclair. (If you have no idea what I'm talking about, watch this video.
So what exactly is a sprite then?
Sprites are just a collection of small images on one single larger master image arranged in a grid that is then mapped or positioned into a smaller space. When computers had less power than your mobile phone it was seen as a resource friendly way to handle graphics without having to load or search for new images everything something changed on screen. There's plenty of examples on Google.
So why should I use CCS Goblins? Umm.. sprites even..
The concept of One Master Image to Rule Them All lends itself to the web really well, reducing image requests happening between the server and client is a Good Thing™ and even better, avoids any of that horrible preloading using javascript.
Its also completely accessible, because no javascript is required and as its all done using CSS your website can contain text alternatives visible to search engines and accessibility software.
And (for once) its a snap to get working cross browser without any CSS hacks (even in IE6).
In short its:
- Faster (no image preloading or multiple image requests)
- Doesn't require bulky javascript
- Accessible
- Search Engine friendly
- Works well cross-browser
Ok, preloading and multiple image suck, I want CSS Sprites
Its actually pretty easy to implement CSS Sprites. The navigation on this site uses it, or view the standalone demo here. The navigation consists of this image

And this HTML:
<ul id="nav">
<li class="m01"><a class="selected" href="/default.aspx"><span>Work</span></a></li>
<li class="m02"><a href="/default.aspx"><span>Blog</span></a></li>
<li class="m03"><a href="/contact.aspx"><span>Contact us</span></a></li>
<li class="m04"><a href="/page/about-us.aspx"><span>About us</span></a></li>
</ul>
Which is then moved around using CSS in an ordered list. Each ordered list element is the exact size for the button, and on the hover state the image is them moved up to display the on state. The trick is to use background positioning to move the image around, the example below shows the main navigation sprite image being set as the background on all our links, and on and off state for the home page <li> navigation element with the background image being moved around depending if the link is in a hover state.
/* do the image replacement (contains all hover states) */
ul#nav li a
{
display: block;
height: 36px;
padding: 0px;
background: url(images/bk_nav.gif) no-repeat;
}
/* off states */
ul#nav li.m01 a
{
background-position: 0px 0px;
width: 115px;
}
/* on states */
ul#nav li.m01 a:hover, ul#nav li.m01 a.selected
{
background-position: 0px -36px;
width: 115px;
}
Of course, there's a little bit more to it that just the background-positioning above, you need to style up your ordered list to be a collection of properly sized horizontal boxes, and move the text in the span tag out of the way. But this post is about CSS sprites and how much they rock, hopefully now javascript rollovers really are dead.
You can download a fully functioning demo here.