CSS Sprites Title

Mo’ Images = Mo’ Problems

My work folder currently has 32,000 files in it. An unbelievable amount of them are images or image related (JPEGS, GIFs, PNGs, PSDs, AIs, etc.). As an interactive designer, I can easily accrue hundreds of images throughout the design (and development) process. While I may let all my local files multiply like rabbits, it’s important not to bring this chaos onto the web. The number of images used in a website design can get wild pretty quickly, so it’s important for us as designers to have a weapon to reign them in, not unlike the Ghostbusters.

What’s a CSS Sprite, Daddy?

Well technically a sprite is just an image.  CSS is then used for separation and reorganization of that image. The sprite itself is generally used to combine many small images into one large image. This is done not only save precious loading time and bandwidth, but also to keep your site structure clean and manageable.

How Image Sprites Save Time

Suppose you have fancy navigation bar on your website, with 8 links. Suppose said links each had a fancy rollover, the kind with that ‘glow’ and ‘twinkle’ that makes your clients drool. In the past (or today if you aren’t yet using the CSS sprite technique) this would require 8 separate images, with another 8 images for the hover state. That’s a total of 16 images for the navigation alone.  That’s 16 files you’d have to create, optimize, name, and save. 16 files you’d have to call in your stylesheet, and upload through FTP. Worst of all, that’s 16 HTTP requests on your server from a visitor. While the images may be very small, each request takes time, and ultimately increases the loading time for your page.

Instead, one could create a sprite showing all of the links with each of their rollover states  as one image. This means one HTTP request. When dealing with dozens of small images, this technique can often cut loading time for images in half.

How the CSS Sprite Technique Keeps it Clean

Here’s some example CSS for 4 links with rollovers. 8 images are called because there is no use of the sprite technique. Each link has its own image, and each link has its own rollover image… these links are greedy.

.link_one {background-image:url(img/link_one.png);}
.link_two {background-image:url(img/link_two.png);}
.link_three {background-image:url(img/link_three.png);}
.link_four {background-image:url(img/link_four.png);}
.link_one:hover {background-image:url(img/link_one_hover.png);}
.link_two:hover {background-image:url(img/link_two_hover.png);}
.link_three:hover {background-image:url(img/link_three_hover.png);}
.link_four:hover {background-image:url(img/link_four_hover.png);}

While that may not seems like a huge problem, imagine if you wanted to change the color of ALL those image links one day.  That’s 8 separate times you’d have to open a file, change a color, and save it. Do this for larger menus, sidebar items, or footer areas, and you’ll quickly have a massive pile of images that you have to maintain. This almost always leads to designers abandoning beneficial changes on their websites because “It’ll take too long!”

Here’s what some of your CSS would look like were you to move all those images into a single sprite:

.link {background-image:url(img/link.png);}
.one {background-position:0px 0px;}
.two {background-position:20px 0px;}
.three {background-position:40px 0px;}
.four {background-position:60px 0px;}
.one:hover {background-position:0px -20px;}
.two:hover {background-position:-20px -20px;}
.three:hover {background-position:-40px -20px;}
.four:hover {background-position:-60px -20px;}

Obviously this is a bit cleaner, but the important takeaway is that if you wanted to edit the look of ALL of these links at once, you could. Simply drop that sprite into Photoshop, re-save, and you’ve fixed them all at once.

Alright, so you understand that it WOULD save you time and energy, but you don’t know how to make a sprite? Who could possibly teach you how to do this on your very own? Perhaps its…

TERRIFIC TUTORIAL TIME!

How to make a CSS sprite based navigation of your very own:

CSS Sprites Slide 1

1. Let’s say you want to make a simple navigation with 4 links. We’ll go with the most basic essential links here: ‘Home’, ‘About’, ‘Pterodactyl’, and ‘Contact’. Go ahead and create a quick mockup in Photoshop of some navigation like this, or apply the following steps to your own current web projects.

CSS Sprites Slide 2

2. Make sure you have one layer set as the default ‘normal’ state. This is how the links will generally appear in your design. Also create another layer that shows all of the links in their ‘hover’ state. In this case I’ve altered the styling, color, and added an underline. Ideally your link size shouldn’t change (If you’re smart you can technically get away with it, just make sure you give ample space for that growth in the sprite, we’ll touch on that later).

CSS Sprites Slide 3

3. We need to single out the navigation now, and make it its own image. You can copy your navigation only, create a new image by hitting Ctrl+N (Cmd+N for Mac Folk), and paste it in. Please note in my example I’ve done a more complex selection around the links, preserving the transparency. You can learn how to do that in my Transparency in .PNGs article, but dragging a simple rectangular selection around your menu items is perfectly fine as well.

CSS Sprite Slide 4

CSS Sprites Slide 5

4. Double the canvas size of your navigation image by choosing Image > Canvas Size… (Alt+Ctrl+C or Alt+Cmd+C). You can double the height without doing any math by simply checking off ‘Relative’ and increasing the height by 100% (or don’t click it, and increase by 200%, I won’t stop you). Your resulting canvas should now have enough room to paste in your ‘hover’ version below your ‘normal’ version.

CSS Sprites Slide 6

5. Uh oh! Remember I said the link size shouldn’t change, and this is why. Adding an underline technically makes the ‘hover’ links a bit taller than the ‘normal’ links. Simply giving room for the bottom underline will cause a huge headache later on in the CSS. We’ll need to add space on the bottom of each row.

CSS Sprites Slide 7

6. In this case, adding 3 pixels to the bottom of each row did the trick. If your links have added hover effects, just be sure to include extra space in the sprite so that the corresponding normal link is the same size. That’s true for both horizontal and vertical space.

CSS Sprites Slide 8

7. Now you can eliminate the negative space in your image. This slightly decreases your file size, but more importantly it makes the bit of math we’ll do in the CSS much easier. You won’t have to count the pixels in between the margins of your sprite if you simply line everything up next to each other. The amount of background-position shifting will simply equal the width of the previous link! That was the most boring statement to ever warrant an exclamation point.


.______ {
display:block;
height:__px;
background-image:url(______);
margin__:__px;
float:____;
}
.nav {
display:block;
height:24px;
background-image:url(img/navsprite.png);
margin-left:24px;
float:left;
}

8. The first CSS class you need to write is your parent class. This is the main class that holds all of the similar properties for your navigation. In my case, all of my links are 24 pixels high with a margin of 24px between them. The margin might not be necessary depending on how you styled your links, but in this scenario a quick ‘margin-left’ will work. The background image will obviously be the same for all of our links (that’s the whole point), and the ‘display’ block is simply used because we will be defining a height and width to each of our links.


.______ {
width:__px;
background-position:__px __px;
}
.home {
width:68px;
background-position:0px 0px;
}

9. The second class you need to write applies to the individual link itself. You’ll need to write one for each link in your navigation, as well as another for each hover state (which we’ll get to in a moment). In this case the ‘home’ link has a width of 68 pixels. The ‘background-position’ refers to the point that the background-image will begin to display from. Since ‘home’ is in the upper-left, both the x-axis (horizontal) and y-axis (vertical) will start at 0 pixels.


.home {
width:68px;
background-position:0px 0px;
}
.about {
width:81px;
background-position:-68px 0px;
}
.pterodactyl {
width:165px;
background-position:-149px 0px;
}
.contact {
width:109px;
background-position:-314px 0px;
}

10. As you can see, all 4 links now have their own widths. You can measure the width of each link with your ruler tool. The key here is that each subsequent link is being shifted by a negative number on the x-axis. On the ‘about’ link, it’s essentially telling the background to start 68 pixels deep into the image (where the ‘about’ link just happens to start in the sprite).

Note: Remember that the background-position is cumulative. You must add the measurement of each previous link each time you enter in the position for the next. In this case 68 pixels and 81 pixels is 149 pixels.  Then the ‘pterodactyl’ link is quite wide, another 165 pixels, meaning our ‘contact’ link’s x-axis position starts at -314 pixels. It’s only addition (or subtraction), but a mistake in one early link will mess up the math for all your subsequent links. So double-check frequently!


.home:hover {
background-position:0px -24px;
}
.about:hover  {
background-position:-68px -24px;
}
.pterodactyl:hover  {
background-position:-149px -24px;
}
.contact:hover  {
background-position:-314px -24px;
}

12. To create a ‘hover’ state for your link, simply copy the class and add ‘:hover’ after the class name. It’s unnecessary to repeat the ‘width’ property. Because all of the hover links are directly under the normal links, the y-axis shift is the same as the link height: 24 pixels. It’s a lot simpler here, as you can just paste that in over and over again.


.nav {
display:block;
height:24px;
background-image:url(img/navsprite.png);
margin-left:24px;
float:left;
}
.home {width:68px;background-position:0px 0px;}
.about {width:81px;background-position:-68px 0px;}
.pterodactyl {width:165px;background-position:-149px 0px;}
.contact {width:109px;background-position:-314px 0px;}
.home:hover {background-position:0px -24px;}
.about:hover {background-position:-68px -24px;}
.pterodactyl:hover  {background-position:-149px -24px;}
.contact:hover  {background-position:-314px -24px;}

13. Here’s the completed CSS for the example. All that’s left is to add the links themselves into the HTML.

<a class="nav home"></a>
<a class="nav about"></a>
<a class="nav pterodactyl"></a>
<a class="nav contact"></a>

14. Simply apply both the parent and child classes to each link. In this case ‘nav’ and ‘home’, or ‘nav’ and ‘pterodactyl’ etc.

You just learned something! Specifically, how the CSS sprite technique works, why it is used, and how to create a slick, efficient navigation out of it. Go get yourself a drink. Or get me one, this baby was looonnng.

Give me your thoughts on this technique in the comments!

You can be first to know about new art prints & limited edition poster releases on the Fringe Focus Newsletter! New art each month. You are also entered to win a poster giveaway (at random) each month! Join thousands of Fringe Focus subscribers.