Clinton Montague

Developer, learner of things, functional programming enthusiast, hacker, and all round inquisitor.

Better, faster and more robust rollovers with CSS sprites

December 9, 2008

Do you remember the olden days? You know, the ones where we had 56k modems, a mouse with only two buttons, and the only way to have a rollover state were those horrid MM_SwapImage javascript functions (or whatever they were called). I do. And I remember that it was actually only a small number of years ago. A large proportion of people are still using javascript for this task, maybe they’re stuck in their old ways. I want to show you a much sleeker, and if I’m honest, a much sexier way to do the same thing. If you can’t wait, I have put together an example.

So what’s a sprite

A sprite is essentially a picture. They can be 2d or 3d and are normally animated or move in some way. Strange to use a different word, but you know what us geeks are like. We like to make things sounds more complicated than they actually are, all the time. How many acronyms go into the technology of this page, for instance. WordPress is built in PHP using the MySQL database. It was uploaded with FTP, to a LAMP server which I manage using SSH. The pages are serverd over HTTP and are XHTML which is styled using CSS which is also used to position the PNG image in the header. Ok, ok, I’ll stop, you get the picture. So a sprite is an image. Think of a picture of Spritetm if that will help. (lol?)

What’s wrong with Javascript?

Nothing! Please, be my guest, continue using javascript until your heart is content. But it will become content. It’s a lot of work having to put your images in an array, get the hover states working independently and hitting your head against your desk. Then ofcourse, there’s always that annoying paranoid troglodyte of a client who has their javascript disabled so can’t see your beautiful handiwork.

Why is your CSS method so great then, huh??!

Sure, my client could have CSS disabled just like yours had javascript disabled. But then, my CSS disabling client is used to only seeing the web in 16pt times new roman with blue links. Using this CSS instead of swapping images will, believe it or not, improve the semantic meaning of your code. Which means google and friends will understand your site better too! Sounds too good to be true, doesn’t it! Shall we press on?

The theory

The idea here is to create a fully standards compliant, fully accessible and gracefully degradable graphical button using only HTML and CSS.

Let’s start with the the HTML for a graphic and turn it into a link, like a normal image link.

My button

Problem number 1: It’s not accessible. Well, sure, it’s got an alt tag, but let’s be pedantic here. Solution: Let’s remove the image and replace it with the text. After that, set the a tag to be displayed as a block (which allows you to specify the height and width), give it an id (so we can pick it out), give it a class of button (there will be other buttons like it so may as well use this to style it up) then use the picture as a background image.

	Sexy button
.button
{
	display: block;
	width: 184px;
	height: 35px;
}
#sexy-button
{
	background-image: url(sexy-button.png);
}

Great! Oh, except for the fact that the text is over the button. So let’s surround the text with a span, then tell the span to go away with CSS.

.button span
{
	position: relative;
	left: -9999px;
}

Wasn’t it supposed to move?

Welcome to the magic of CSS sprites. Remember how those rollover buttons were made of two graphics, one for the on state and one for the off state? Well use some photoshop glue to place them on top of each other (the off state at the top). I know, I know, it’s bigger than the size of the background, but that’s the awesome thing! Now, using only css, we can move the position of the background when the user rolls over the anchor tag using the :hover psuedo class.

.button:hover
{
	background-position: 0px -35px; /* moving up by the height of the button */
}

AND because it’s just a single image, the user won’t see the short delay and flicker when they roll over your button because the browser doesn’t have to load a new image!

The applications of this are immense. Just imagine having the on, off and active states all in one image and all controlled with your new friend, css. If you have gone on to use this, post a link to your new page!

And for graceful degradation:

You can download the files in the example page.