Learning CSS Sprites

What exactly is a sprite? It’s a CSS technique that can make your website load faster. Instead of having a dozen images that are included on every page of the site (one for your logo, one for an RSS button, a few fore social media links, etc.) you combine them all into one big image. You can then use CSS to display just the portion you need in any given spot.

How does this improve loading times? The major bottleneck in the loading of a web page today isn’t download speeds so much as concurrent downloads. A web browser will only download two files at once from a web server. After the HTML is downloaded, the browser has to grab CSS, JavaScripts, and images from your server. You might have a lot of those secondary files, and only two will be loaded at once. If you combine your template’s images into one big file, they all get downloaded at once, instead of two at a time. Also, you may shave off a few kilobytes of file size in some cases, but that’s not as important.

Now how does this trickery work? Let’s use Apple.com as an example. They keep their header navigation in a sprite that looks like this:

Apple navigation header sprite

As you can see, the buttons are laid out in a row, with their alternate states underneath them. A sprite starts out as something just like that: an image full of little images. The real trick is making it spritely.

Let’s start with the HTML. Here is a simple block of HTML links wrapped in a parent DIV. Each item has an id assigned so we can address it in the stylesheet.

<div id="sprite">
<a id="button-1">Apple</a>
<a id="button-2">Apple</a>
<a id="button-3">Store</a>
<a id="button-4">Mac</a>
</div>

Now the first thing that needs to be done in the stylesheet is to collectively select all of the a elements with a CSS rule. I made them all block-level with the first attribute so they’re each on one line, which will make the output look tidier to better illustrate things.

#sprite a {
display: block;
width: 117px;
overflow:hidden;
height:0px;
padding-top: 38px;
background-image: url('path/to/sprite.png');
margin: 5px;
}

The width and overflow lines in the above CSS snippet define some of the dimensions of the elements. The width is self-explanatory, and the latter ensures that the element doesn’t expand to a different size if the textual contents of the link are too big. Then the height and padding-top lines are used to set the height of the element. Instead of directly setting the height to 38px, the padding trick is used to make the plain text inside the links invisible. Otherwise it would appear over the image background.

The background image is then included. Now things get interesting…

#button-1 {
background-position: 0px 0px;
}
#button-2 {
background-position: 0px -38px;
}
#button-3 {
background-position: -117px 0px
}
#button-4 {
background-position: -234px 0px
}

These CSS rules are simple but powerful. The background-position attributes set which part of the image is displayed. Since we’ve already defined a width and height for the elements, only a small slice of the image can be visible at a time. The background-position lines simply define which slice that is.

The first selector, #button-1, sets the top-left corner of the element’s background image to be at position 0,0 (the top left corner) of the image. For #button-2 we shift it down 38px, #button-3 right by 117px, and so on. It may seem a little odd at first, but you’ll get the hang of it eventually.

You can even do “rollovers” with sprites. Just use the :hover pseudoclass or a JavaScript mouseover trigger and shift the sprite to the desired spot by changing the CSS property on the fly.

Sprites example

  • Pingback: designfloat.com

  • http://www.shoutmeloud.com Harsh Agrawal

    Hey man, very nice post. I have reading about CSS sprites at lots of places..but never actually thought of using it. Though have no clue if I can really use it.. But your articles giving me lot of suggestion and I will try and see if I can use it, else I will come back for questions…:)

  • http://twitter.com/problogdesign @problogdesign

    Nice tutorial Matt. This is a perfect example of CSS sprites in use. They speed up loading times of course, but once you're used to working with them, I find that setting up a navbar like this with CSS sprites is actually easier than doing it any other way as well! Really useful trick :D

    • http://intensedebate.com/people/redwall_hp redwall_hp

      It does seem to be a much more elegant solution for navbars, and I've been using simple sprites for that for awhile now, but I'm just starting to get into more advanced ones. I'm currently working on a new version of the Webmaster-Source theme (same design, but with functionality and under-the-hood changes) that will put a bunch of the assorted images into a sprite. The logo, badges in the sidebar, things like that.

      I only wish that it require so much trial and error to get the background offsets just right. I'm always off by a few pixels it seems, which means tweaking the numbers a little at a time until things line up properly. :)

  • manish patel

    Wow , great tutorial ..
    instantguide.org

  • Gossip Everyday

    Hey man, very nice post. I have reading about CSS sprites at lots of places..but never actually thought of using it. Though have no clue if I can really use it.. But your articles giving me lot of suggestion and I will try and see if I can use it, else I will come back for questions…:) http://www.gossipeveryday.com

  • http://genrontech.com Pooja

    After your article seeing, I thing I should learn more on CSS work. such a great work man. I can still make my website look more attractive by using some high quality CSS work and some of animation. Now my website is not so cool. Will make it soon.

    Genrontech.com