posted on:October 29, 2008

Creating easy and useful CSS Sprites

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:

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:

CSS Sprite Example

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.

Width and Height of the Sprite Images

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.

2px Leftover in the CSS Sprite

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.

Defining the background-position of an image in the Sprite

.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.

Enjoyed the article?

Then don't miss our next one! Subscribe to our RSS feed or share it with your friends.

DeliciousStumbleUpon RedditSubscribe

Comments (18 Comments)

  1. E.J. Semeijn
    October 29, 2008

    Love it! Definitely going to use it!!
  2. Scott
    October 30, 2008

    Nice tutorial. The HTML does not have to be image tags. The technique can be used with virtually any HTML element. I like using sprites with the anchor tag and moving the background image for :hover states (which, again, could be done with virtually any HTML element).
  3. Jon Hartmann
    November 3, 2008

    Its probably worth noting that this technique only works for anything as long as you have a fixed height or width. For example, if you have a menu that is 30 px tall and displays one image normally, and another on mouse over, you can combined the 1x30 px images into a single sprite and use the :hover state like Scott said to do the swap. This avoids flickering while loading the 2nd background image like you would normally have.
  4. Christian Dalsvaag
    November 7, 2008

    In practice this seems obviosly smart. But; the size of the sprite is: individual_image_size + individual_image_size +... And all these images individual also are the same size? Or? So if you're not going to use all the images in the sprite for each load - you're wasting bytes, in stead of gaining?
  5. Atatürk posteri
    December 11, 2008

    thank you so much.. this is nice article
  6. Programmatore PHP
    December 16, 2008

    It is usefull and your article is explained very very well! Thank you
  7. ellm
    January 19, 2009

    And for those who look at the page without CSS Style... ?
  8. migaber
    January 27, 2009

    nice fast and helpful tutorial ,thank you :)
  9. Leena Ajwani
    February 13, 2009

    hey that was really cool article. I will bookmark it and try to use in our next project. thanks
  10. paolo
    February 26, 2009

    I'm sorry but how can apply css sprite to rollover buttons using pseudoclass a: ? tank a lot
  11. Jim
    April 2, 2009

    Hi Ignacio, 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
  12. *PEACE
    April 5, 2009

    very useful article. thanks a lot.
  13. admin
    April 25, 2009

    kişisel web sitesi olup bayrak tanimi ve bilgisi içermektedir
  14. Mike
    April 28, 2009

    @Christian: at first glance, without understanding the technical protocols behind the web, it might seem that simply adding up the image sizes may be larger than the 'compressed' CSS sprite image. However, each new image to be loaded also has overhead - the HTTP transportation - which results in latency. If you save 1 single HTTP transport request and have to load a couple of bytes additionally (e.g. parts of the sprite not used), it's still a good deal.
  15. Kellen
    April 29, 2009

    Additionally @Christian 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.
  16. Rifa
    May 19, 2009

    i want to know, how can i insert this code into my blog. i want to use the css sprite within my content wrapper. but i don't know how.
  17. Serzhik
    June 15, 2009

    <img src="s.gif" class="i1"> = 28 bytes <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 " ")
  18. forma
    June 17, 2009

    Forma örme kumaş ve iplik hammaddesi olmak üzere üretim yapilan bir çeşit giysi türüdür. Genelde iki parçadan oluşur. Üst ve alt takimi olarak üretilir. Tek parça forma yapimida mevcuttur.Futbol maçlarinda kullanilan formalar likra ve polyester katki içerir. Milli sporlarda kullanilan forma oyuncunun en önemli eşyasidir. Formanin yapisi itibari ile oyuncunun vücut isisina göre ter çekme özelligi vardir. forma Genelde Milli Sporlar, bayrak yarişlarinda Olimpiyatlar, Basketbol, Futbol, Valeybol, Dövüş sporlari, Yüzme Sporlari v.s. kullanilir.

Sorry, the comment form is closed at this time.