Let's start with the basics. What are CSS sprites?
CSS sprites are a way to combine images to improve our page loading time, reducing the number of requests our server does. In this article I will teach you how to make them.
Take a look at the demo | Download zip file
To make clearer what a CSS sprite is, here is an image of a CSS Sprite made by Google:
When you make a search in Google, you have a bottom pagination. And you get something like this: Gooooooooooooooogle. The letter 'o' is repeated using the CSS sprite, so instead of loading 15 time the letter, it just loads the sprite with all the letters in it, once.
Creating our CSS sprite - Step 1: Making the image
Ok, first of all we must make our sprite image. You can make it in Fireworks, Photoshop, or whatever software you use. Here is mine:
As you can see, the sprite consists in a bunch of images divided between them by a 1px width line. This division is not really needed as you can see on the Google Sprite, but it makes our lifes easier when we get to the CSS. Believe me.
Step 2: Creating our sprite image revealer
Once we make our sprite image, we must make a transparent 1PX x 1PX gif image. This image will later be the one which will reveal our different images inside our sprite.
Step 3: Creating our CSS code
First of all, we will create the class 'sprite', which will load our sprite image.
.sprite {background:url(../images/mySprite.png);}
After loading our sprite, we must define the height and width of the images inside it.
As all my monster images have the same height, and all the application images too, I can give them a class to share their height. I will use the classes: 'monster' and 'application'.
.sprite {background:url(../images/mySprite.png);}
.monster {height:128px;}
.application {height:61px;}
Now, we must define the width of every image, because they are all different. We will use a class for each one of them.
.sprite {background:url(../images/mySprite.png);}
.monster {height:128px;}
.application {height:61px;}
/* Monsters */
.doctor {width:103px;}
.octopus {width:89px;}
.wolf {width:115px;}
.star {width:126px;}
.dog {width:128px;}
/* Applications -*/
.css {width:61px;}
.activityMonitor {width:58px;}
.dashboard {width:51px;}
.quicktime {width:53px;}
.scanner {width:74px;}
All done? Ok, here come's the good part. We must define a background-position to every image in order to show correctly. This background-position must always have negative values, because our background image must move left, to reveal the different images.
We must make every image inside the sprite move to the top left corner, because that is the spot where we begin seeing the image. That corner is equal to 0px in X, 0px in Y.
My Sprite, however has a left and top leftover of 2px, so we must take that into account when we define the background-position of the elements.
Remember the first value of background-position, is horizontal (x-axis) and the second one is vertical (y-axis). Let's finish our wolf. Our wolf must move 196px left and 2px up.
.sprite {background:url(../images/mySprite.png);}
.monster {height:128px;}
.application {height:61px;}
/* Monsters */
.doctor {width:103px;}
.octopus {width:89px;}
.wolf {width:115px; background-position:-196px -2px;}
.star {width:126px;}
.dog {width:128px;}
/* Applications -*/
.css {width:61px;}
.activityMonitor {width:58px;}
.dashboard {width:51px;}
.quicktime {width:53px;}
.scanner {width:74px;}
Now let's finish all our images using the same method:
.sprite {background:url(../images/mySprite.png);}
.monster {height:128px;}
.application {height:61px;}
/* Monsters */
.doctor {width:103px; background-position:-2px -2px;}
.octopus {width:89px; background-position:-106px -2px;}
.wolf {width:115px; background-position:-196px -2px;}
.star {width:126px; background-position:-312px -2px;}
.dog {width:128px; background-position:-439px -2px;}
/* Applications -*/
.css {width:61px; background-position:-2px -133px;}
.activityMonitor {width:58px; background-position:-64px -133px;}
.dashboard {width:51px; background-position:-123px -133px;}
.quicktime {width:53px; background-position:-175px -133px;}
.scanner {width:74px; background-position:-229px -133px;}
Take a look at the Y-positioning of the elements. It's the same for all the monsters, and all the applications. That is because they are aligned in the same vertical position; ergo, they all share the same distance to the top edge.
Step 4: Creating our HTML code (piece of cake)
<img src="images/transparent.gif" class="sprite monster doctor" alt="Doctor Image" /> <img src="images/transparent.gif" class="sprite monster octopus" alt="Octopus Image" /> <img src="images/transparent.gif" class="sprite monster wolf" alt="Wolf Image" /> <img src="images/transparent.gif" class="sprite monster star" alt="Star Image" /> <img src="images/transparent.gif" class="sprite monster dog" alt="Dog Image" /> <img src="images/transparent.gif" class="sprite application css" alt="Css Image" /> <img src="images/transparent.gif" class="sprite application activityMonitor" alt="ActivityMonitor Image" /> <img src="images/transparent.gif" class="sprite application dashboard" alt="Dashboard Image" /> <img src="images/transparent.gif" class="sprite application quicktime" alt="Quicktime Image" /> <img src="images/transparent.gif" class="sprite application scanner" alt="Scanner Image" />
Define de source as the transparent 1PX x 1PX gif image we created before, apply the clases and it's sprite time!
Limitations of this method
For a CSS sprite image to work, it must always have a width, height and background-position. If you don't define the width or height of the element, you will see the whole sprite in that image. Quite obvious but is good to mention.
The icons in this tutorial
The icons used in this tutorial are the Somatic Xtras 2 Icons created by David Lanham.
E.J. Semeijn 29 Oct, 2008
Scott 30 Oct, 2008
Jon Hartmann 3 Nov, 2008
Christian Dalsvaag 7 Nov, 2008
Atatürk posteri 11 Dec, 2008
Programmatore PHP 16 Dec, 2008
Thank you
ellm 19 Jan, 2009
migaber 27 Jan, 2009
Leena Ajwani 13 Feb, 2009
paolo 26 Feb, 2009
using pseudoclass a: ?
tank a lot
Jim 2 Apr, 2009
Great tutorial. Would you use the same procedure if you did not have 2 heights with your images? I am thinking of a background for a menu where all images are same height and width.
Thanks
Jim
*PEACE 5 Apr, 2009
admin 25 Apr, 2009
Mike 28 Apr, 2009
Kellen 29 Apr, 2009
If they are going to view those other images later in the site, they now are cached. Also like there is overhead for initiating an HTTP request, there is overhead inside of image file formats. Especially formats like GIF that have color tables and compression tables. In an example I just tested, a 4x4 GIF is 824 bytes, with another random 4x4 image added to it to be 8x4, it's 828 bytes... not even counting server HTTP request overhead that's a huge savings.
Rifa 19 May, 2009
Serzhik 15 Jun, 2009
<div class="i1"> </div> = 28 bytes
... but ...
<img src="images/s.gif" class="i1"> = 35 bytes
<div class="i1"> </div> = 23 bytes (use 160 symbol, not " ")
forma 17 Jun, 2009