How to increase the performance of a website with CSS Sprites

You’re created a website, maybe using our “How to build a website from A to Z” guide, but you’ve noticed that loading times are rather long. There could be many reasons to explain this behavior, and there are some small tweaks you can implement to increase performance. Today we will talk about CSS Sprites.
What are sprites?
When you’re developing a website, it’s common to use background images that can create certain effects not possible using only XHTML+CSS. For instance, you can use them to create headers that have a peculiar font, or for menu buttons as well. Just to give you a more concrete example, let’s imagine a menu divided into four, and then create the following images:
![]()
Apply these images to the ‘hover’ state, using CSS:
In total, 8 images, meaning 8 requests to the server, are requested; one per image.
A sprite is a series of images combined into one, divided into sections and edited through CSS. Looking at the example, you will see how the images are combined in the following way:

The concept of a web sprite derives from the 1980s videogame era, when it was first developed to allow character’s movement across the screen. (Monkey Island’s famous Guybrush Threepwood is depicted in the image).
![]()
Nowadays most of the popular websites use this type of imaging: this is an example found on Google websites:
![]()
How can I improve image menus using sprites?
Let’s see how you can create the menu shown in the example using the two methods, after which you will be able to notice a difference in the site’s overall performance. Start with a simple XHTML markup, a list of links:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <link rel="stylesheet" type="text/css" href="no_sprites.css" /> <title>Menu without sprites</title> </head> </body> <ul id="nav"> <li class="home"><a href="#">Home</a></li> <li class="about"><a href="#">About</a></li> <li class="contacts"><a href="#">Contacts</a></li> <li class="portfolio"><a href="#">Portfolio</a></li> </ul> </body> </html>
As you can see, each link has a class associated to it so that you can combine the CSS code. First let’s do some basic formatting, such as a reduction in margins and some editing to the text:
body,h1,ol,ul,li,p{margin:0;padding:0;}
body{
background-color:#FFF;
color:#000;
font:75%/1.4 Helvetica,Verdana,Arial,sans-serif;
}
Now remove the default styles from the list and align the elements by applying a float on the left side:
...
#nav{
list-style:none;
margin:20px;
}
#nav li{
float:left;
margin:0 4px;
}
...
Look at the result, it looks like you’re on a good track: the elements are properly aligned horizontally and have a margin separating them. Before applying the images, it is important to change the dimension of the links so that they fit the image. In this case the dimensions are 100 pixels in width and 27 px in height:
#nav{
list-style:none;
margin:20px;
text-indent:-9999px; //this rule hide the text
}
#nav li a:link, #nav li a:visited{
display:block;
width:100px;
height:27px;
}
...
The display:block directive is very important, since it allows the entire area of the link to be clicked instead of just the text. You can also hide the link text, using the text-indent function. Let’s proceed by applying the images:
...
.home a:link, .home a:visited {background-image: url(home.png);}
.about a:link, .about a:visited {background-image: url(about.png);}
.contacts a:link, .contacts a:visited {background-image: url(contacts.png);}
.portfolio a:link, .portfolio a:visited {background-image: url(portfolio.png);}
.home a:hover, .home a:focus {background-image: url(homeh.png);}
.about a:hover, .about a:focus {background-image: url(abouth.png);}
.contacts a:hover, .contacts a:focus {background-image: url(contactsh.png);}
.portfolio a:hover, .portfolio a:focus {background-image: url(portfolioh.png);}
...
This part of the code might look intimidating, but in reality the rules are really simple: due images are associated to every class, one to define “normal” and “visited” states, and one for the “hover” and “focus” states (this last one is activated when a link is selected using the Tab key). The end result is functions perfectly, but you can still improve it through sprites. Note how the first time you hover the mouse over the link, there’s a slight delay in the transition between the two images: this delay is due to the loading time of the hover image. Let’s look at how to solve this.
How do I use sprites?
To understand how sprites work, think of looking at a poster through a small opening on a piece of cardboard. You’ll see that the angle of vision is limited, thus not allowing you to see the entire poster in one view and only providing you with a section of the image.
![]()
As you can see in the image, using CSS we can move the background image. Since we have changed the link dimensions in the previous step, we are certain that only the relevant image portion will be visualized.
Another advantage of using sprites is that a minimum amount of change is made to the code, which interests only the CSS portion. The first edit is going to involve adding the same background image to all of the menu links:
...
#nav li a:link, #nav li a:visited{
background-image: url(menu.png); //single image for all links
display:block;
height:27px;
width:100px;
}
...
Once you have completed this, you will have to position the background by inserting the proper coordinates for each element. You can find these coordinates using any image-editing program, such as GIMP or Photoshop. In this case, it’s relatively simple, since all of the elements are of the same size. Let’s see how it comes out to be structured:
...
.about a:link, .about a:visited {background-position: -100px 0;}
...
Here we have used the background-position rule using horizontal and vertical movement as our parameters in the following order. As you have seen in the descriptive image, the “About” button used to occupy a space 100px from the left border and 0px from the top one. Since we will have to move the image to the left, the value to be inserted will have to be negative. The position of each element can be found by doing some simple arithmetic:
.home a:link, .home a:visited {background-position: 0 0;}
.about a:link, .about a:visited {background-position: -100px 0;}
.contacts a:link, .contacts a:visited {background-position: -200px 0;}
.portfolio a:link, .portfolio a:visited {background-position: -300px 0;}
.home a:hover, .home a:focus {background-position: 0 -28px;}
.about a:hover, .about a:focus {background-position: -100px -28px;}
.contacts a:hover, .contacts a:focus {background-position: -200px -28px;}
.portfolio a:hover, .portfolio a:focus {background-position: -300px -28px;}
And this is the final result.
Closing comments
The use of sprite images in the development phase of a website is not given much value. It can take several hours to create a sprite image, but one must also consider the advantages one gets in return. Most importantly, these are in the request load sent to the server, as well as the size of the downloaded files (as a matter of fact, the total image is smaller in size compared to all of the single images put together). Test results on the example we showed you in this article show that the version with multiple images has a loading time of 3.82 seconds. This is due to the continuous loading of the images in the “hover” state. While for the sprite version, a loading time of only 0.521 seconds was recorded.
A total savings of almost 50% is made (considering the loading times of a page).
However, a few remarks must be made: we feel that this technique is useful once a definite version of a site is created. This is because creating a sprite which contains all the elements of a site is quite intensive.
So we advise you to use single images during the development and testing phase, and sprites for the definite version of the layout. What do you think about it?
*****************************************
L'immagine principale dell'articolo è stata fornita da @Fotolia
16 comments
Trackback e pingback
-
How to increase the performance of a website with CSS Sprites | Design Newz
[...] How to increase the performance of a website with CSS Sprites [...] -
You are now listed on FAQPAL
How to increase the performance of a website with CSS Sprites... You’re created a website, maybe using our How to build ...




You said above : “It can take several hours to create a sprite image” – I’ve started using this – http://codecanyon.net/item/css-auto-sprites/85409
saves hours of time.
Thank you Gary and welcome to YIW.
That script looks really useful, thanks for sharing.
Do you have a real example using that script? I’m a little curious of seeing it in action “into the wild”
Just started using sprites and must admit its easier then you first think, great article thanks!
Welcome to Yiw, Bonx,
it really just take a little thought.
Thank you for replying.
Nice tutorial, usefull
Thank you, Tutorijali.
Do you use any sprites in your works?
Nice post. I’ve been using sprites of late on some projects we have in development and it’s been really useful.
Just did some quick searching and found a free css sprite generator – http://csssprites.com/ (haven’t tested it yet, but there are also others out there).
Thank you Mike, and welcome on YIW
There are many sprite generators spreading throughout: I really need to investigate some of them. Thanks for the link
Great tutorial! I appreciate the step by step walk through.
Now to check out some of those sprite generators . . .
Thanks so much Ron.
We always try to be as much clear as we can
Enjoy your staying
Great Article…… Also, Good job using Guybrush Threepwood from Monkey Island as the Sprite Example! Haaha!
Thank you Eric, and welcome to YIW.
Guybrush is my personal hero
Css sprite is really important for your website it reduce your web page loading time and make it now lots of web page analyzers software indicate to use it
Yes! CSS Sprites boosts site performance and reduce several lookups while loading images on your site.