CSS Sprites

CSS sprites have been around just about as long as CSS has been around - they just haven't been called that. And recently they have matured into a more viable technique that can help speed up your site. So let's begin at the beginning... To explain CSS sprites I'm going to ask you to imagine a typical horizontal navbar...

Now imagine that when a user rolls over a nav item the background changes color. Simple, right? Just create one class for the normal state with one background image and one class for the hover state with another...

a.nav-item {
  background-image: url(/images/navitem_bg.jpg);
}
a.nav-item:hover {
  background-image: url(/images/navitem_bg_over.jpg);
}

...and we're good to go - sorta. What happens the very first time a user rolls over that nav item? Since they have never requested that rollover image, the client browser has to ask the server for it and the user has to wait for the .jpg file to download. But this is all happening while the user should be seeing our snazy rollover effect.Even if it only takes a half-second to load its very jarring to have a delay. (Not to mention the server has had to handle yet another request from the client, but I'll get back to that later.)

There are typically two solutions to this problem. The first is to use javascript to pre load the rollover images like this:

<script type="text/javascript">
  var img = new Image();
  img.src = "/images/navitem_bg_over.jpg"
</script>

But that requires javascript and even now there are those people that don't have it turned on, plus you need to remeber to add an extra line of javascript for every rollover image. This can get unwieldy quickly.

The second option is to use a CSS sprite. Finally it's time to explain what exactly this is. Instead of using two images to handle this nav item, what if we only used one? And then used background positioniong to show the correct area of that image for each state. Something like this:

sample css sprite

a.nav-item {
  width: 120px;
  height: 25px;
  background: url(/images/navitem_bg_both.jpg) 0px 0px;
}
a.nav-item:hover {
  background-position: 0px 25px;
}

Now what if we went a step further and put all the images needed for the entire navbar into one image and used the same technique to set the background image position for each nav bar item in both its normal state and it hover state. So now the user downloads just one image file (which is usually smaller than the sum of all the little images) and he never has to endure that millisecond delay I mentioned earlier.

sample css sprite

There is a catch though. Using this technique will mean that the very first time a user visits your site it will take longer to load because he is downloading that large image up front. On the other hand, that image will now be cached on his local computer so he shouldn't have to download it again until you make a change.

A couple of things to keep in mind. Don't over do it - try not to put every image on your whole site into one file or you'll find yourself wading through it forever looking for things Keep things organized. I find it a best practice to have one CSS sprite for the navbar and another for (let's say) emoticons. This way the files are organized for easy management No white space. I know this goes against all your design instincts but the less white space you have the smaller your file will be and you gain nothing by including it.