Display icons using a single image and CSS “Sprites”


Recently, I have been working on a website that has numerous icons being displayed on a single page. One of the ways to reduce server requests is to store all of your icons in a single image and use CSS to display only the portion of the image you need for a particular location on your page. This technique is commonly used by designers to display icons from a single image. It is often termed CSS sprites.

First, lets take a look at an image with the icons we will be using. I have chose these grunge icons for this example. You can find icons on just about any stock photography site or if you are adventurous make your own.

Web Icons Display icons using a single image and CSS
Icons we will use for displaying via CSS

The setup

First, we need to figure out the grid of the icons on this image. The image dimensions are 204 pixels wide by 136 pixels high. Simple math tells us the height of each icon is 68 (136 ÷ 2). The width of each image is also 68 (204 ÷ 3). Nice!

Using CSS, we will display each icon in it’s own DIV tag. To do this, we will use the left and top values of the background-position property. The background-position property defines the initial position of a background-image. You can find specifics of the background-image property at w3c.org. I prefer to map out each of the icons top and left coordinates before I write the CSS. It makes it much easier. Here is the image with the coordinates mapped out for you.

Coordinates for images
This shows the top,left coordinates for the image to be displayed using CSS.

Those aren’t coordinates! Well, no. They are not Cartesian or polar coordinates. They are a special type of coordinate that defines the leftmost and topmost margin of the given image. Negative margins shift the image up and left. So the coordinates (-136,-68) when used in the CSS property of background-position:-136px -68px would render the margin to start at the top left corner of the shopping cart icon in this image. So with that in mind, we can now build our containers for the icons.

When I’m developing I like to break out my CSS into logical functions. In this case I want to create a class for the container that will contain the icon. Something like this should do just fine.
.icon {
background-image:url('images/web_icons.png'); /*your location of the image may differ*/

A base class now exists that pulls the proper image that contains the sprites as well as defines the height and width of the container. Next, we need to create a
class that will display the given icon from the image. I like to break this out by icon type. Here are the classes I set up for this image.

.person {background-position:0px 0px;}
.info {background-position:-68px 0px;}
.upload {background-position:-136px 0px;}
.document {background-position:0px -68px;}
.check {background-position:-68px -68px;}
.cart {background-position:-136px -68px;}

The final step to get these to display is to create the containers. We need to create six separate containers and add the proper classes. Here are the divs we will use to display the icons.
<div class="icon person">
<div class="icon info">
<div class="icon upload">
<div class="icon document">
<div class="icon check">
<div class="icon cart">

In the above example, I have taken the class .icon and the class representing that icon and put them together in the class attribute. Using multiple classes is a great way to apply styles without having to repeat code in your CSS.
The following screenshot shows you how the code to this point should render in a web browser:



With a single image and some CSS styling you can easily display various parts of the image on your page. The options are limitless. Using floats and absolute positioning you could place the containers anywhere on the page. You can easily apply the :hover pseudo-class to the appropriate element and have the image shift when the cursor is over that element. We will address this in another tutorial. Do keep in mind that there are some browsers that don’t support the :hover pseudo-class, namely IE (big surprise!).

There are sites that use CSS sprites extensively. I came across one just the other day. Kaleidoscope essentially uses one large image for many of the graphics on their home page. You can see the full image here. While keeping server requests down may seem minor it is the kind of foresight and good coding that can help a site become scalable in the long run.

Happy designing!

Recommended for you:

22 thoughts on “Display icons using a single image and CSS “Sprites””

  1. ive been wanting to learn this and i guess ive give it a try since this tutorial makes it look easier , before im still a bit confused about this, its time to get a hand on this to learn, thank you for this brief guide

  2. Much thanks, i read about this idea in OReilly “building scalable webapps”, but never tried it – now, since everything is getting bigger and bigger, i decided to give it a try and to reduce server requests 🙂

  3. While it may seem efficient there are drawbacks to this method.

    1. In a real world setup the initial load time is actually much greater because you have to wait until the entire file is downloaded before ANY page can begin to get rendered. Having separate image files can render the page viewable in less time because you are not downloading OTHER not needed images which will download when you enter a page that calls for them.

    2. Compression and quality is actually crippled. Not everything is the same size, colors and need the same compression. So having everything on the same file means you sacrifice quality or sacrifice SIZE because you can’t have both. In real world setup you would be able to compress everything and only keep very few quality pieces that has to be quality for certain requirements.

    3. These days with the rising SPEED of ISP’s and hosting services it’s not that great of a speed boost to put in so much sacrifice and effort on getting one sheet to do it all.

    4. Myth. There is no hard solid evidence that this beats single files. I’ve not seen my friends website beat mine of load time simply because like I said. His single image is quite large compared to my tiny bits and pieces.

    Now it’s up to you to decide if this is truly all that.

  4. I have been wondering how the multi-image PNG files worked for a while, and now I know – CSS Sprites. A useful guide, thank you.

  5. Thanks for sharing, another advice is also to combine all your sprites into one file to reduce the amount of http loads. By reducing the http loads, you are able to make your website load faster.

    Although combining all your sprites into one file and making use of background-position css property is a pain in the ass, it is worth your time.

  6. Sprites are fantastic for hovers and all sorts, a great example of where sprites are used fantastically is facebook – the whole site is practically one sprite.

  7. @Ash Excellent point. I wouldn’t use this for sites with a small number of icons to display. I have found that hovers can be frustrating as well.

  8. I know our web designer gets asked to use icons here and there and, luckily, he is very talented and doesn’t have a problem with it. But I’m still going to have him take a look at this.

  9. I’ve known about this for a long time but never seen an opportunity to use it until a week ago on a client website. It’s actually pretty efficient if you use more than half a dozen icons on the page, it keeps http requests down.

    It does get a little tedious working with hover’s which i did have to use, but i think i will use this a lot more often from now on.

    Thanks for the article!

Leave a Reply

Your email address will not be published. Required fields are marked *