While it’s far from being a new technique, the use of CSS sprites is one of my favorites, for a number of reasons.
First and foremost, there is no arguing that they are good for load times. We’ll discuss why in a bit. Another plus: they make it a lot easier for you, the site owner/designer/editor/tinkerer to keep your images organized. Why keep track of an ever-growing list images on your server if you can simplify things into a single file? Sprites just make sense – but hold on, I think I’m getting ahead of myself here…
Let’s start with some basic vocabulary. A “sprite” in the context of webpages is a collection of images in a single file.
They originated back in the earlier days of video game consoles… hence the retro image at the top of this post.
Basically sprites allow you to save a group of images in a single file. This way you can load the same file for all of the images on a page, and use CSS to display just the section you want.
The reason this is so valuable is because it allows your web pages to load a lot faster – especially for pages that contain a lot of images and/or get a lot of traffic.
So, how exactly do sprites accomplish all of this? I thought you’d never ask!
Decreasing HTTP Requests
Every image your visitors have to load on you site means their web browser has to initiate an HTTP request to your server.
These requests are easily one of the most arduous steps in the process of loading your page, so too many of them can start to slow things down.
The beauty of sprites is that once an image is loaded, the browser can reuse that file as much as it wants without making another HTTP request, so if you have ten images on a given page, a sprite could eliminate nine extra requests!
Sprites Are Small!
Another added benefit is the fact that sprites are smaller than the total size of their individual parts.
Let’s look at the image on the right as an example. This sprite is a series of buttons that are used on a business overview page of a different site (click the image to see a larger version in a new window). As you can see in the full size image, this sprite contains two versions of seven different buttons – so it’s doing the job of 14 separate images!
The size of this file is just under 160KB – but if I were to split the 14 images up into their own files and load them separately, they would total approximately 196KB – an increase of over 22%.
So with this sprite, we’re not only cutting the HTTP requests down from 14 to just 1, but also cutting a good chunk of the data out of the process.
Creating A CSS Sprite
Okay, let’s get to the good stuff already! The first step is going to be creating the image, so you’ll need to open up your favorite image editor.
Before you create the sprite, you should have your individual images handy. Once they are all organized and ready, you can get started.
Firstly, decide how you want to lay out your sprite. A lost of sprites are arranged in a single column, but you can go horizontal, or create a grid with rows and columns (like the sprite I’m working with). It really just depends on what your image dimensions are, and what you like working with.
Basically, you need to decide how big your final image needs to be. To accomplish this, add the dimensions of your images together, and include at least one pixel of blank space between each one (unless of course, your images already have a little background space built in).
For the sprite I’m working on, I have seven images to line up side-by-side, and I’m making two rows. Most of my buttons are 281 pixels across (with white space included), and the seventh button is only 202 pixels wide. So basically, my sprite needs to be (281 x 6) + 202 for a total of 1888 px.
Since all the buttons are 80px tall and I need two rows, my final image is going to be a total of 1888px across by 160px high.
First thing I need to do is place my first image. You can arrange them however you want, but I generally recommend placing them in the order they are going to appear on the page – but that’s more for your benefit as the person editing this image in the future, and writing the CSS to utilize it.
If you’re going with a single column or row, place your next image(s) immediately below or beside this image, leaving a pixel of white space in between if needed.
When you’re done, you should have all your individual images lined up without overlapping or touching (it’s okay if the background color of your images touch, just not the images themselves).
Save the file and upload it to a folder that you can easily reference from your CSS stylesheet (whatever folder your current theme uses for images should work just fine).
CSS Sprite Code: Making It All Work
Now we’ve come to the REALLY fun part: the code that hides/displays the appropriate section of the image. Now, I’m going to be using this sprite to control links, so the first step is to define all of the styles that all these links will have in common (in my case that’s things like size, outline, margins, background image, etc. My first piece of CSS looks like this:
/*Shape and Background*/
div#demo a {
display:block;
outline:none;
text-align:center;
width:281px;
height:80px;
margin:20px auto;
background:url(http://welcometowp.com/wp-content/uploads/2011/08/businessinfobuttons.jpg) no-repeat;
}
You’ll notice I’m referencing anchor tags in a unique div with the ID of “demo” in this CSS. It’s generally a good idea to isolate the the elements you want to control with a sprite in their own ID or class so you don’t affect other elements on the page accidentally (Example: I don’t want to turn every link on this page into a 281×80 pixel box – it would be pretty messy).
With this CSS I’ve set all the links in this div to have the same width and height. Since one of my buttons is narrower, I’ll override the width for that button individually, like this:
/*Narrow Home Button*/
div#demo a#home {width:202px;}
This type of override is a good example of how the entire process works. You’ll notice that I’m still referencing my “demo” div, but then I’m going a step further and looking inside that div for a specific anchor tag with the ID “home.”
This is how you target your CSS to effect only a specifically nested element – meaning if I had a link with the ID “Home” that was outside the “demo” div, this CSS wouldn’t touch it, because this style only effects elements that are nested in this specific location.
Let’s see how our buttons look so far:
I’m going to display three of the buttons to save space, but we’ll look at all of them at the end of the demo. Here’s the code I’m putting inside my “demo” div:
<a id="watch"><span class="hidetext">Product Line</span></a> <a id="product"><span class="hidetext">Product Line</span></a> <a id="home"><span class="hidetext">Compensation Plan</span></a>
Now, a couple of things about this code. Firstly each link has it’s own unique ID – we’ll need that later, so make sure it’s in place. Secondly, you’ll notice that there is a span with the class “hidetext” attached to each – that’s there to hide the link text that normally appears (this is accomplished with a simple “display:none” on the stylesheet).
The third thing is that the destination URL’s are missing – that’s just because I don’t need them for this example – you’d obviously want to include them so the buttons actually take your visitors somewhere.
Now, as you can see, we have a couple of problems. First of all, all the buttons look the same! The only exception is the “Home” button at the bottom (even though it doesn’t say “Home” yet), which is narrow enough that it cuts off part of the image – thanks to the nested CSS we added earlier.
The buttons are all identical because we specified the same background image back in our first block of CSS – now we have to move that image around to display the right section for each link.
That means adding in a little more specifically nested CSS – this time pointing to the unique ID’s that we’ve attached to each link.
The second problem is that the buttons don’t do anything when you click on them – when we’re done, they’ll actually appear to press down when clicked, but that’s the next step.
For now, we’re going to focus on making the individual images display for the right buttons. To do that, we’re going to add some CSS that targets each button individually, and in those styles we’ll provide specific coordinates for where the background image should be displayed:
div#demo a#watch{background-position:top left;}
div#demo a#product{background-position:-281px top;}
div#demo a#home{background-position:-1405px top;}
On the first line, you’ll notice that I’m defining the background position as “top” and “left.” This tells the browser that the top of the background image should align with the top of the element, and the left edge of the image with the left edge of the element.
These coordinates can be words like top, bottom, left, right, and center, as you see in the first entry. They can also be numbers of pixels designating where the image should start – and you can mix and match like I’ve done here. Whenever you use pixel designations or the “center” value, make sure you’re listing the x-axis (horizontal) first, because that’s the order the browser will read them in (top, bottom, left and right are specific enough that you can get away with listing them out of order if you really want to).
The second line is where it gets fun. For the horizontal value, I’ve specified that the image should start at -281, or 281 pixels (the width of my buttons) to the left. That means the first 281 pixels of the image will be hidden, since the are beyond the left hand edge of the element.
If that part is at all confusing, just imagine that the top left hand corner of your element (in my case an anchor tag) is sitting at coordinates 0,0. All you need to do is adjust the position of your image from there.
Now, since I skipped down to the “Home” button for this little demonstration, the next line starts the background image at -1405 pixels, which is how far I need to “slide” the image over to get my “Home” image to show up. Let’s see how these three buttons look now:
Viola! Our CSS is now automatically loading our background image, and placing it so that the right section is visible for each of the three buttons! You can add as many rules as you need to for as many images as you want.
Now, as an added bonus, let’s add some CSS to make the buttons appear to actually “click” when a visitor hits them (try clicking one now – nothing happens. Super boring!).
What we’re going to do here is add more targeted CSS that will this time grab the pressed state images I included in my sprite. In my sprite these are all on the second row, so I only have a little bit of copying, pasting and editing to do so that I can add this:
div#demo a#watch:active{background-position:left bottom;}
div#demo a#product:active{background-position:-281px bottom;}
div#demo a#comp:active{background-position:-562px bottom;}
And the result appears to the right. Go ahead, give ‘em a click!
Only a couple of small changes in the code here. First off, when adding these lines of CSS, I added the :active to each of the selectors. That tells the CSS that I want it to apply this style when the element is clicked.
Second, I changed the background positions from “top” to “bottom,” because the images I want are on the bottom of my sprite.
If I had more than one layer, and needed to work my way down the sprite, I could change the vertical values to -80px, -160px, etc., just as we did for the horizontals.
Finishing It All Up: Organize Your Code
The only thing I have to do now is add in the links for the rest of my buttons, along with their ID-specific CSS styles, and then clean up the CSS a bit. For buttons like these, I like to put the two styles for each button together, rather than grouping all of the basic images with the pressed versions – but that’s just a personal preference. Here’s the CSS I end up with to tie it all together:
/*Shape and Background*/
div#demo a {
display:block;
outline:none;
text-align:center;
width:281px;
height:80px;
margin:20px auto;
background:url(http://welcometowp.com/wp-content/uploads/2011/08/businessinfobuttons.jpg) no-repeat;
}
/*Narrow Home Button*/
div#demo a#home {width:202px;}
/*Hide Text*/
div#demo a span.hidetext {
display:none;
}
/*Clicky-Clicky*/
div#demo a#watch{background-position:top left;}
div#demo a#watch:active{background-position:bottom left;}
div#demo a#product{background-position:-281px top;}
div#demo a#product:active{background-position:-281px bottom;}
div#demo a#comp{background-position:-562px top;}
div#demo a#comp:active{background-position:-562px bottom;}
div#demo a#team{background-position:-843px top;}
div#demo a#team:active{background-position:-843px bottom;}
div#demo a#start{background-position:-1124px top;}
div#demo a#start:active{background-position:-1124px bottom;}
div#demo a#home{background-position:-1405px top;}
div#demo a#home:active{background-position:-1405px bottom;}
div #demo a#comp-pdf{background-position:-1607px top;}
div #demo a#comp-pdf:active{background-position:-1607px bottom;}
}
Which leaves us with these buttons, all with unique images and fully functioning click action:
And that’s really all there is to it!
- Create your images
- Combine your images
- Write your general style rules for all of the elements
- Assign a unique ID to each element
- Write some targeted rules for each elements unique ID
- Have a nice day!
By following these steps, I’m now able to display all of the buttons used in this post with a single HTTP request, and using a noticeably smaller amount of bandwidth!
Sprites like these can be used for almost anything, not just buttons. You could use them for graphic bullets if you write a lot of lists, or even create fancy images of numbers for numbered lists. You can use sprites to display fancy titles on things like sidebar widgets: the sky’s the limit. Virtually anywhere you use an image, you can incorporate a sprite to speed things up.
Hopefully now you’re on your way to adding your on sprites to your pages, but as always, leave any questions or problems you run into in the comments!

0 Responses
Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.