Grow your CSS skills. Land your dream job.

CSS Sprites: What They Are, Why They’re Cool, and How To Use Them

Published by Chris Coyier

This post was originally co-authored in late 2007 by me and Volkan Görgülü, I'm updating it now to improve it a bit and make it more current.

You've heard of them, but...

Do you really understand them? The name might be a little misleading, because sprites aren't little images like you might be picturing, a sprite is actually one big image. Have you ever seen the CSS technique where the "on" and "off" states of a button are contained within the same image and are activated by shifting the background-position?

Here is an example of that on CSS-Tricks.

Think of CSS Sprites as an extension of that technique. The difference is that instead of just two or three images being combined into one, you can combine an unlimited number of images into one. The origin of the term "sprites" comes from old school computer graphics and the video game industry. The idea was that the computer could fetch a graphic into memory, and then only display parts of that image at a time, which was faster than having to continually fetch new images. The sprite was the big combined graphic. CSS Sprites is pretty much the exact same theory: get the image once, shift it around and only display parts of it, saves the overhead of having to fetch multiple images.

Why combine all those images? Isn't it quicker to have smaller images?

Nope, it's not. Back in the day, everybody and their brothers were "slicing" images to make pages load faster. All that technique did was fool the eye to make it look like the page was loading faster by loading bits and pieces all over at once. Each one of those images is a separate HTTP-Request, and the more of those, the less efficient your page is.

Let's look at a quote from the article "Performance Research, Part 1: What the 80/20 Rule Tells Us about Reducing HTTP Requests" by Tenni Theurer on the Yahoo! User Interface Blog.

Table 1 shows popular web sites spending between 5% and 38% of the time downloading the HTML document. The other 62% to 95% of the time is spent making HTTP requests to fetch all the components in that HTML document (i.e. images, scripts, and stylesheets). The impact of having many components in the page is exacerbated by the fact that browsers download only two or four components in parallel per hostname, depending on the HTTP version of the response and the user's browser. Our experience shows that reducing the number of HTTP requests has the biggest impact on reducing response time and is often the easiest performance improvement to make.

Table 1. Time spent loading popular web sites
Time Retrieving HTML Time Elsewhere
Yahoo! 10% 90%
Google 25% 75%
MySpace 9% 91%
MSN 5% 95%
ebay 5% 95%
Amazon 38% 62%
YouTube 9% 91%
CNN 15% 85%

Every single image, whether it's an <img> tag or an background-image from your CSS is a separate HTTP-Request, so you can imagine how quickly those requests can rack up.

OK. So how is it done?

I thought you would never ask. Let's start by showing the BEFORE example. Notice in the CSS below how the anchor tag does not get a background-image, but each individual class does.

#nav li a {background:none no-repeat left center}
#nav li a.item1 {background-image:url('../img/image1.gif')}
#nav li a:hover.item1 {background-image:url('../img/image1_over.gif')}
#nav li a.item2 {background-image:url('../img/image2.gif')}
#nav li a:hover.item2 {background-image:url('../img/image2_over.gif')}
...

example1before.png

Using CSS Sprites, we can really lighten this example up. Instead of having ten separate images for the buttons (five default states and five rollover states), we can literally combine all of them into one big long image. I won't go into great detail about how this is done, I'll just give you a basic walkthrough. Create a new image that is as wide as your widest image and and as tall as the combined height of all your images plus X pixels, where X is the number of images you have. Now place you images into this new image, left aligned, one on top of the other with one pixel of white space in between.

Now check out the AFTER example. Notice in the CSS that there is a single background-image applied to the anchor element itself, and the unique classes merely shift the background position with negative Y coordinates.

#nav li a {background-image:url('../img/image_nav.gif')}
#nav li a.item1 {background-position:0px 0px}
#nav li a:hover.item1 {background-position:0px -72px}
#nav li a.item2 {background-position:0px -143px;}
#nav li a:hover.item2 {background-position:0px -215px;}
...

example1after.png

We were able to reduce the number of HTTP-Requests by 9 and the total file size of the image(s) by 6.5 KB. That's a pretty huge improvement for such a little example. Imagine what you could do on a full website.

 

Ugh. That sounds like a lot of work.

Just remember what Chuck Norris once said: "All great things require great dedication." Actually I'm not sure if he said that or not, but it's good advice anyway. But fortunately for you, there is a web service which makes creating and implementing sprites really easy. There are actually lots of different services designed to help you making sprites easier, but I think hands down, the best one is SpriteMe.

Using SpriteMe

SpriteMe is a bookmarklet. So after you've put it up in your bookmarks bar, just go to any website and click it. It will open up an overlay over the right side of your screen.

The top white box is a list of all the background graphics on your page that it feels like could be combined into a sprite. The boxes below are graphics that probably won't work for sprites (and it will tell you why). If you think differently, you can drag the links in and out of their boxes. Once you have all the images to be combined in that top box, just click the "Make Sprite" button. It will combine them all into a single image (a CSS Sprite!) that you can view right there.

On the current design of this site, this is a (scaled down) version of the end result. (Or see the real thing)

Recently, SpriteMe also made it available to "export" the CSS. Click that button and you'll see some code like this:

A id=home-link
{
  background-image: url(http://cdn.css-tricks.com/wp-content/themes/CSS-Tricks-4/images/logo.png)
  background-image: url(http://www.jaredhirsch.com/coolrunnings/public_images/3deb155981/spriteme1.png);
  background-position: -10px -10px;
}
A
{
  background-image: url(http://cdn.css-tricks.com/wp-content/themes/CSS-Tricks-4/images/nav.png)
  background-image: url(http://www.jaredhirsch.com/coolrunnings/public_images/3deb155981/spriteme1.png);
  background-position: -10px -56px;
}

The crossed out code is what used to be in your CSS, and what the replacement should be is below it.

What can't sprites do?

They don't do repeating graphics*. Sprites are for graphics that are just single blocks. Icons are a great example candidate for CSS sprites.

*OK, they kinda can do repeating, but it's a little trickier and can only work one-dimensionally (x or y).

Either start from the beginning with Sprites, or do it all at the end

The using of sprites is a no-brainer. You should do it. But what is the workflow when creating a new design? I think you should go one of two routes. The first is to know that you are going with sprites from the get-go and built it as you go along. That means have a Photoshop file open, start from the upper left, and drop stuff in as you need it. If you have another icon (or whatever) that makes sense to put in a sprite drop it in there and resave it.

The other way, which perhaps makes even more sense, is to develop without thinking about sprites at all. Make everything separate individual graphics. Then when the site is "complete" (or at least, ready for release, we all know sites are never "complete"), then use SpriteMe and do the spriting then.

Other Examples

Just food for thought...

Ask.com

Google Reader icons

Facebook

Further Reading

Comments

  1. Good post! Will be one to bookmark and look over!

    Another good thing about CSS sprites is that you can do columns easy as well. For a previous website I tried having three columns equal length and it was next to impossible until I used sprites for one background image.

  2. I’ve seen this technique used for a number of years, but mostly in navigation before.

    While I understand the principles behind it, it really just doesn’t make a lot of practical sense (aside from the request argument) to do this.

    The reason I mainly dislike this probably comes from my bias of having worked on a site using it, that I didn’t originally design. I didn’t have the original graphic files, and it was a pain to have to try to recreate it from scratch (when all I wanted to have to do was change one little icon and not have to worry about the other 4 in the same graphic).

    Better site performance, maybe a little. I would say the biggest time hit on most sites are server-side these days, especially with all the database driven platforms out there now.

    It’s worth it if you’ve got the time I say, but I say especially if you are under deadlines it could cost you more than it’s worth.

  3. @spiralstarez: I think you make some good points. Updating graphics is a lot bigger of a pain with sprites, especially if you don’t have the native files.

    I think there is probably a sweet spot where using CSS sprites is the most beneficial to use. If you have a fairly low traffic site on a decent server…yeah…it probably doesn’t matter to much. If you are running a super high traffic news portal like yahoo.com, there are definite benefits and using them to reduce server requests is a must.

  4. lucy barker
    Permalink to comment#

    Interesting article.

    I would point out, however, that if a user increases font-size, then the neatness of this option starts to fail as you get to see the other images revealed. Perhaps a slight change in approach would work a little better: make the composite image run horizontally, rather than vertically.

    Also min-heights might be employed in the css to prevent the images collapsing when font-size is decreased by the user (not that that is so likely).

  5. Permalink to comment#

    Chris,

    Nice job writing this up in a manner that most people can understand. I have been using sprites for rollover navigation for quite some time and I do find it’s the best way to go in terms of page load times.

    Lucy makes a great point about sprites having trouble when font sizes scale, Definitely want to encourage people to test their designs at a variety of font sizes.

    Also – if you’re going to talk sprites, you have to mention one of the coolest sprite examples out there on Ask.com. Here’s a link directly to their sprite image: http://sp.ask.com/i/h/sprite/b1.png

    Cheers,
    Scott

  6. Permalink to comment#

    Great article

    As you mentioned at the start I had used them for individual on-off navigation states but had never thought of this technique for multiple images!

    Thanks Chris!

  7. I had seen this done before – but your way of explaining it makes a lot more sense.

  8. @lucy: Great point! Yep, you can absolutely make your sprites run horizontally instead of vertically. In fact, you can do both, Just take a look at the awesome example sprite that Scott linked to below (from ask.com), which uses all kinds of X and Y positioning.

    @Chris & Matt & Scott: Thanks! I appreciate your guys support.

  9. Permalink to comment#

    We’re using this technique in http://xhtml-css.com too :)

  10. Permalink to comment#

    Lucy Barker,
    That explains why I’m not seeing it right. I was reading this in a feed-reader and saw underlines under the squares when I clicked on the example. They were the tops of the next squares. When I opened the example in Firefox, the bottoms of the squares were cut off, and increasing the font size brought them back, but also revealed some of the square below.

  11. Thanks for this article, it really enlightened me on my strategic approach to websites. Thanks again.

  12. Volkan Görgülü
    Permalink to comment#

    Leaving more whitespace between images can be a solution to the degradation which happens when the font-size is increased or decreased.

  13. Permalink to comment#

    http://www.shacknews.com has been using CSS Sprites for a few years now.

  14. Spongebob Tesseractpants
    Permalink to comment#

    Ugh. Ultimately, the sane solution is to *stop using bitmapped graphics*. As screens get higher and higher resolution, just using SVG would be so much nicer. Pity you can’t rely on it being available (time was, you couldn’t rely on PNG being available, of course, so maybe one day…).

  15. Maintainability for this approach could be achieved pretty easily by incorporating the process of combining images into the system build. The SCCS would maintain the original separate images, and it’d be at build time that they’d be turned into the single super-image. The stylesheets would have to be done as templates, using artifacts of the imagine combining step to fill in the actual super-image coordinates.

  16. Permalink to comment#

    I first came across sprites on paulstamatiou.com
    Btw, is there any way to use sprites for elements other than links, and for repeating bg? I’m doubtfull abt the last one.

  17. Excellent post. Fascinating reading. I’ve posted it over at InformedNetworker.Com…and I’d be happy to have you submit your article links for any future postings such as these you feel might be useful for your readership.

  18. @Sumesh: I don’t think there would be any practical way to use sprites for a repeating image, just because the best way to do it is to know your height and width of the element you will be using the sprite on and it is unlikely you would know that for an element you are trying to use a repeated image on.

    But you can absolutely use sprites for things other than links. Anything that accepts the background-image property in CSS is fair game.

    • Permalink to comment#

      Yahoo! uses bg sprites for repeating backgrounds (here’s an example — from their home page ) pretty extensively, but your caution, as well as the cautions above, about knowing your width/height are really important. It’s problematic, especially if you’re just starting off. It’s definitely an advanced technique, and an easy one to be tripped up on. (I’ve done it, and been tripped!)

      If you ‘have’ to do it, I think the key is plenty of whitespace between backgrounds and extensive testing.

    • Andrew
      Permalink to comment#

      Keep an eye out for css3. It won’t be in many browsers soon, but we should eventually be able to use sprites for fully repeating backgrounds.

      http://www.css3.info/image-sprites-syntax/

  19. Some Jackass
    Permalink to comment#

    Part of the reduction in size is simply because GIF is limited to 256 colors, so this isn’t a totally fair comparison. If you closely examine the colors in the image after splicing, you’ll see that they are subtly different from what you had before. For most icons you can’t tell the difference, but on an effect with heavy gradients, you would notice it. Unfortunately this effect compounds itself as you add more images. If you use PNG – you’ll see that most of the reduction in file size goes away.

    Of course, the main point is that cutting down on the number of files you have to grab from the server is a good thing (even with pipelining and HTTP/1.1), and that point stands. But given the reduction in clarity, (and if you use GIFs, image quality) is that worth the cost?

  20. Stoyan
    Permalink to comment#

    Here’s a CSS sprites tool I did:
    http://www.csssprites.com
    (The UI is pretty ugly, I must admit, but if anyone wants to contribute a stylesheet, that would be much appreciated, link-back-acknowledged, etc)

  21. One small notice – if your image sprites are .PNG files with alpha channel, the transparency hacks for IE6 will break your css styles. AlphaLoader filter doesn’t support background-position property,the backgrounds are automaticly positioned in the upper left corner. so you’ll have to serve gif sprites to IE6 or use single PNG images for it.

  22. @Some Jackass: You are right, part of the file size savings comes from the fact that the total color palette for all the images will be forced into 256 colors at a maximum rather than having 256 for each image. But even if you used few enough colors on each image there would be no compromise, there would still be slight savings from not having to repeat file format code each time. Not much, but some.

    @Matas Petrikas: Thanks for pointing that out. In short, when using PNG hacks, don’t use sprites.

  23. Permalink to comment#

    Re: Matas’ comment – it’s OK to use PNG sprites without any hacks in those cases:
    a/ your PNG has constant transparency (true/false, like a GIF). In this case the so-called PNG8 format can be used where you have 1 bit for transparency
    b/ the PNG has variable transparency, but is saved with 4 bits for transparency

    PNGs for a/ can be produced by lots of tools, for example imagemagick on the command line:
    > convert my.png PNG8:my8.png
    PNGs of type b/ are only produced (AFAIK) by Fireworks (Fireworks calls them PNG8)

  24. @Stoyan: Could you explain a bit more about the 4-bit PNG transparency? I’m really only familiar with PNG-8 and PNG-24 from Photoshop. Using PNG-8 (1 bit transparency), no hack would be needed. Using PNG-24, using the hack would break the sprite because of the hack. Are you saying there is another way to save a PNG that would support alpha transparency with no hack needed?

  25. Stoyan
    Permalink to comment#

    Hey Chris, a differet format is what I meant – Fireworks calls it PNG8 but looking at the result image with imagemagick’s “identify” I see 4 bits for transparency.

    The long story here:

    http://www.sitepoint.com/blogs/2007/09/18/png8-the-clear-winner/

    • Permalink to comment#

      I don’t know how extensively this Fireworks PNG8 was tested. I ran through a test run with one image, which seemed to work fine, and then went to use it with a gray gradient image, and it did not render properly. There might be an algorithm that tries to detect what “should” be alpha transparency or something, but it was definitely “broken” for this one case.

      I wouldn’t rely on it.

    • Felicity
      Permalink to comment#

      @Greg with PNG 8, “Pixels are either solid or completely transparent, but never partially see-through.” – so it wouldn’t have work with a gradient as the alpha levels would have needed to vary

  26. Permalink to comment#

    Love the comment bout Chuck Norris :P I don’t think I’ll really use it, the space saved in minimal with today’s broadband speeds. I may try it out in future designs just for the heck of it though :P

    • I think you missed the main point – the saving is with the 9 fewer requests – avoiding 4-9 latency hits for the end user (which doesn’t depend on their connection speed) and giving your server less work to do.

  27. Shane
    Permalink to comment#

    Great article, but I have to pick at one technical issue. One of the main reasons for slicing was *not* to trick the eyes into a faster loading experience, but rather to optimize large gifs.

    You see, a gif can be significantly compressed if the corresponding color pallete for that particular image can be minimized. Therefore a large area within a gif of the same (or similar) colors can be factored out, via slicing, to greatly reduce the total size of the whole image. In other words, the size of all the slices combned would be less than that of the whole image, unsliced.

    Of course, the landscape has greatly changed and with increasing usage of jpegs and PNGs, and increased bandwidth of users, response time (round trip) becomes much more of a factor than simply bandwitdh. Nevertheless… great article!

  28. @Shane: You know, I remember when I was sitting there writing this, I was paused tapping my forehead thinking of just why the heck we used to cut apart images like that. I used to to it all the time, but I couldn’t remember for the life of me why I did it. I don’t think I ever thought about it, it was just the standard.

    But yes, you are absolutely right, the real reason was the color indexing power of GIFs.

  29. Kakupacal
    Permalink to comment#

    But what about applying alt tags to the images for 508 compliancy? Is it possible?

  30. Permalink to comment#

    @Kakupacal – the sprites technique is best suited for background (decoration) images. Your page should work well and be accessible even with no background images.

    For “content” images, it’s still best to use img tag with alt attribute. For example a photo in a news article is part of the content and should be an img tag

  31. Permalink to comment#

    Yahoo DevNet does believe “CSS Sprites are the preferred method for reducing the number of image requests” but they have a lot of other recommendations for making fewer HTTP requests as well, besides their general list of best practices.

    I really appreciate the attention to detail in this post, Chris!

  32. Chris
    Permalink to comment#

    Thanks for putting this together. Finally a nice static image example. I would like to set this up for our website but I think it would be a good idea to get all the images I want first so i don’t have to go through the process again in a couple of weeks.
    Thanks so much
    Chris

  33. Are there any known problems for this in IE5/6?

    I’ve put sprites to use in 2 areas for a new site on a larger scale than i have before.

    previously I had done this just for the down and hover state of individual nav elements. then put them in their definded spot.
    this time i have 1 graphic for 5 individual links both having down and hover states.

    in all browsers the site is working right, so far, except in IE5 and 6.

    its duplicating the whole image at its full width on the Y axis 4 times. then at the 5th time its showing the button with its hover state as it should.

    lol driving me crazy.

    i dont expect anybody to solve this problem as its hard to explain but I’m hoping somebody has had some problems with sprites in IE6 that can offer some information on the background repeating or at least seeing that effect despite having no-repeat value called on the declaration block.

  34. I have yet to figure out exactlly what was causing my problem but I think it did have something to do with applying the same 1 image to all A elements in my UL instead of individual images for each A element.
    i had to apply a 0px height for ie to the LI and A elements of my navigation.
    odd.

  35. This is great. I have used this technique before with 3 state navigation… 1 image with the position manipulated by the css based on off/hover/active. This really opens things up. Where you would maybe dynamically load images in a rotation on a page load, rather than a dynamic image load, just make it dynamic css positioning. Thanks for pointing out the further possibilities of this technique!

    Thank you,
    Jim Summer
    Jacksonville Web Design

    http://tentonweb.com/

  36. Really useful hint, there are lots of possible implementations of this technique.
    I’ve found myself preferring the “slicing” of images, I hope it wouldn’t be hard to change it.

  37. Permalink to comment#

    Actually Chuck said “All great technique require great dedication”.

  38. Nicely put Chris,

    The technique doesn’t end with iconograhpy.
    I started redevelopment of my own site and this time it’s quite graphically intensive.
    I used the sprite technigue on the complex background and was shocked at the difference.

    http://websemantics.co.uk/new/

    In Firefox right click on the page background then view the background image.
    Click the image to zoom to full size and you’ll see all the background gradients stacked vertically.
    It’s also worth noting it’s a compressed .png so there is no image quality loss.

    Page load speed, both actual and percieved, is incredible in comparision to the previous trials.

    This technique, while problematic and time consuming, is most certainly worth it.

    regards

    mike

  39. Nice work Mike. Good example of using the sprite technique for different purposes. I would think that if someone where extremely dedicated, you could make an entire complex layout with a single image.

    • Robert
      Permalink to comment#

      Chris

      I’m actually trying to do exactly this. Thankfully it’s not a large image, but I’m only using one image to change between states when the user clicks on buttons overlayed on the image. It’s more complicated than I had hoped.

  40. seekingalpha.com has built its ENTIRE SITE using css sprites.
    you can really learn from it greatly !

  41. This somehow sounds like HTTP needs an overhaul – and this suggestion is a workaround.

    • Permalink to comment#

      Not really a workaround. HTTP will never be “overhauled”. What this technique does is streamline/optimize.

      Optimization isn’t workaround any more than code refactoring is!

  42. Thanks for putting this comparison together, it really illustrates the size and speed improvements that can be achieved with a little extra planning and work.

  43. Beth
    Permalink to comment#

    I use this technique all the time and love it. The only drawback I’ve found is when printing a page in Firefox with sprites, the full image (all states) is compressed into the “masked” area on the printed document. The print preview looks fine, but the pdf/printed output compresses the image. Seems to print OK in IE.

  44. well I think if you give background-position in Percentages, it certainly breaks or shows different in IE-6 than other browsers..Other shows the position as expected..so in such case you need to give the position in Pixels..Do you think is this is the way it is Or i am going wrong else where? let me know

  45. Nodster
    Permalink to comment#

    I like the idea of using sprites (especially for the navigation), however a question has arisen from the Vid tutorial that you did Chris. To offset the nav text you used a negative margin…how do you get around this negative margin when a user has images turned off on their browsers. Yes i know that this isn’t that great an issue with todays bandwiths but it still leaves me wondering as the text will not be on show (if for example the nav is on a banner at the top of a website). Thanks for any answers given to this.

  46. @Nodster:

    There are a great number of ways of handling this besides the text-indent method, which does indeed fail with images turned off.

  47. I’d just like to add that I’m using css sprites on my weblog’s current design. Since it’s a PNG-file I decided to kill some of the graphics for IE6 and older browsers, but it works like a charm for all other browsers.

    For now the logo is a part of the sprite, but I’ll cut it out and place an img-tag at the top div, so it’ll be visible for print too.

  48. shannon

    thank you for your help…sprite111
    sj

  49. I think css sprites are an interesting concept, and possibly well suited for a couple applications like backgrounds and basic button rollovers. However, in a production environment where you have one team prototyping and then handing off to a development team (or handing to a client), it really isn’t practical.

    Just the issues of color integrity, ease of updating, printing problems, no alt-tag support, etc, are reasons enough to not put this into wide practice on a client’s production site.

  50. Permalink to comment#

    While I think I’m getting this gist of this, showing the image you used would help a lot more!

  51. Check out a video podcast example of creating CSS sprites (if you like that sorta thing) here

  52. Hi please, can you help me, css sprites are very interesting, but do they work in internet explorer 6 ??? I have a problem with this..please help, thank’s

  53. Permalink to comment#

    I use this method often, but does anyone know why ie6 decides to “reload” the image every time there is a hover?
    When you hover over the link the already loaded image, disappears then reloads, E-V-E-R-Y single time!!!!

    I heart IE…… not!

  54. Permalink to comment#

    Hello,

    I created a CSS Sprite Generator in PHP (CLI Mode)

    It has the ability to replace the background-Images automatically.

    If you are Interested habe a look here:

    http://tanila.de/smartsprite/index.php

    kind regards
    tanila

  55. Pashaie
    Permalink to comment#

    Hi,

    Thanks for your topic, it helped me to works with CSS Sprites!
    Here is my wired situation:
    I use a large number of css background image (actually 66 images!) for my site. A good percent of these images are used in boxes demonstrations, I can use css sprites trick for left-top & left-bottom corner of boxes, but it seems that there is no way to use in right-top, right-bottom and middles (that must have repeat). Am I mistaken and some how there is some way to achieve this goal?
    if there is no way to use this trick, what’s your suggestion to reduce number of images?
    I’ll be very grateful to have any ans/suggestion sent to my mail: pashaie-at-gmail-dot-com ;)
    Thanks in advance

  56. Permalink to comment#

    Perfect! This is just what I need to squeeze out a bit more performance!

    Thank you.

  57. Permalink to comment#

    Thank you Chris for all your teachings!! Totally Invaluable!! I taught myself ‘sprite navigation’ through your posts and videos and it works great. I have two quarks though… 1.) by moving the text ‘offscreen’ FireFox creates an UGLY dotted box all the way offscreen (used to keyboard navigation). I learned to ‘turn it off’ (outline: 0;) but then… it’s… well, off and difficult for those with accessabiltiy handicaps can’t navigate… Is there a way to just ‘make the text dissapear’ but leave it in position?? 2.) Centering… holy cow… I just spent 4 hours searching the net trying to center the list in my web… no go… I just went for a ‘hack’ to put a left margin on it… Is there a way to center this list?

  58. Permalink to comment#

    Where is the link to the css sprite generator?

  59. @Lucy Now that you can zoom in the most browsers. Designers should be creating static font sizes instead of “em” font sizes, so that you don’t have the background image problem.

    @Brent People who are tabbing hyperlinks should be using their own CSS or disabling all CSS.

    I prefer a middle of the road approach that only creates sprites for the same button. I really hate aligning sprites perfectly, so I’ve created a Photoshop Script that combines two images of the same size to make a simple normal/hover sprite. It’s not as genius as the 20 image sprites you can make online, but it’s much simpler and you can assign a keyboard shortcut to it in Photoshop. I prefer the control of it, and you don’t run into the “I don’t have the source files” problem.

    http://www.smjdesign.com/designwell/archives/photoshop-script-combine-two-images-css-hover-css-sprite/

    Also, does anyone know if you have to re-create/submit files to these online sprite generators, do the files have to be in the same order by their file name, so that they are in the same place and you don’t have to change all of your CSS rules. Seems like that would be a pain to do.

  60. I think that I am going to make an effort to start using this. The only issues that I have is: what if you finish your sprite, everything is perfect but you forget something, something that would require you to redo the entire thing… Then you need to start over, and spend unnecessary time that could be used for something bigger and better.

    • You don’t redo it, you open up your sprite graphic, make it a little taller or wider and drop the new sprite in there and resave it. It’s definitely more work than using individual images but isn’t the end of the world.

  61. Nice article.. I have been using sprites recently and it really effects the page load speed of the website. If we use single images for menu elements and their hover state then while the site is loading, if we scroll over the menu element, then no image is displayed till it’s loaded properly.. Using css sprites voids this problem.

  62. Permalink to comment#

    I noticed this similar technique used on the play.com website quite a long time ago, but never attempted to try it myself.

    This is a nice article, I’m gonna give it a go on a test case and see how it goes.

  63. Nice article Chris, I am a hugeeee fan of css-sprites. I mean check out my sheet for alittlephotoshop.com :

    http://bit.ly/4g4Ncr

    As you said however, the problem is definitely workflow. I recently had to replace the sidebar header images because I was adding a new one. While being on my laptop I had no PSD, so some serious photoshop hack work started. It’s a massive pain.

    Furthermore when you have build your stylesheet on explicit pixel positions, and a graphic then becomes redundant in your site, like in mine the search box was never used. There is basically no way to remove it from the sheet save from recoding the entire thing to prevent file bloat.

    Ultimately, how wonderful a service spriteme is ! I think this will be the last time i hand build sprite sheets. Rather, just build the entire site regularly, upload it, run spriteme and finally save a second version of the stylesheet.

    Making changes to the original and rebuilding with spriteme seems like the most elegant solution rather than hacking up my sheet time and time again to make minor changes.

  64. Permalink to comment#

    You really have a great way of simplifying the this process. It really helped to understand. As others have said, I think planning where you’re going to use them is the most important thing to consider.

  65. Murph
    Permalink to comment#

    Hey Chris,

    What is the best way to integrate Sprites into a WordPress CMS site, so that the PHP generated content plays well with the Sprites? Any suggestions…?

    -Murph

    P.S. – Thanks for the great, informative work you do. I learn something new from one of your sites everyday.

    • Permalink to comment#

      The technique will be exactly the same; WP doesn’t do any magic. The only trick sometimes is identifying where the style is being declared if not in stylesheet.css. Some plugins include their own stylesheets, for example.

      Firebug (Firefox) or Dragonfly (Opera) can be handy here.

      Once you’ve identifies where the css is, you will simultaneously be identifying the source of the images. If they’re separate images, you just need to open them up in your image editor and copy/paste them into your new sprite file and calculate the offsets.

      Greg

    • Murph
      Permalink to comment#

      Thanks, Greg. Think I’ll give this sprites thing a shot in my next design!

  66. This is one of my most favorite things about CSS. I managed to reduce my template to just 3 images since there’s always all these scripts and other files that like slowing down my site.

    Some say that managing sprites is hard, but I think the exact opposite, especially for hovers. Having all those images in one file helps it easier to organize and find them later to edit. Say I’m looking for something in the header, well if you have some sort of “header.png” file, you have your nav and everything in there just like you might have a folder/directory on your server.

    I’m against services like SpriteMe, because it’s more of a static solution. If you’re constantly editing your images or find yourself changing your site a lot design wise, you will need to sprite up all the files again and maybe even change the css just for one small change.

  67. Oh and for those who think it’s just not worth it even speed wise, take my header sprite for example. If all those were single images, it’d take forever for my site to load. I don’t have problems editing it either, so that’s a personal issue.

    http://cdn.myunv.com/img/resource/sitewide/assets.sprite.png

    Sorry for the double post :(

  68. Permalink to comment#

    Nice roundup Chris! I’m not new to sprites, but I liked how you mentioned what they can’t do (repeating images) and showed some examples from well-known sites.

    I’ve found that Mint has some large image sprites for its icon sets.

    • You can do repeating graphics as long as they go only in one direction (repeat-x or repeat-y).

      If you have other images within that sprite that are larger than your gradient, you would simply stretch it to fill the whole width or height.

  69. Permalink to comment#

    Good post, I’ve been using sprites for navigations and buttons for a while. I’ve been hesitant to use much larger sprites, with many graphics in one file because of my fear it will slow down the rendering of the page. Even though you can’t “see” the rest of the sprite image, you could have a bunch of 1000px x 1000px sprite files all over your page. Are there any studies showing if this hurts rendering performance? Am I just being paranoid?

  70. Great article on CSS sprites, I found the tips very useful as a newbie to CSS!

  71. Permalink to comment#

    Brilliantly written article as ever.

    I’ve been aware of sprites for a while now but never really had the urge or justification to start using them. Part of my dubiousness towards them comes from file management and the aforementioned editability (is that a word?!) implications. The idea of “[opening] up your sprite graphic, make it a little taller or wider and drop the new sprite in there and resave it” makes my overly anal organisational tweak rear its head.

    Also as someone who does a lot of work fiddling with pre-written Joomla plugins and the like, the idea of not being able to investigate an element, see its background image, create a new one (potentially of a completely different size), upload and replace in favour of sifting through a png image and bloating it with new sprites seems a bit impractical. Obviously it’s a small point in a large discussion but it’s a definite no no for open source developers…

  72. Permalink to comment#

    Excellent idea to update and republish this article.

  73. OMG, I am getting addicted to the CSS-TRICKS.com. I was worrying that CSS and other these stuffs like Sprites will be very advanced and hard to understand, But the way you explained made the fear to vanish and I can understand it fully.

  74. Permalink to comment#

    Check out Mashable.com they’ve got a pretty slick CSS sprite goin’ on

    Mashable Sprite

  75. Great article. I myself use web developer toolbar to check the images other sites use and I’ve seen this many times. I figured it revolved around positioning a single image. I never understood the concept of it more clearly before reading this article. I’ll be sure to implement this in my blog design.

  76. Arch Focus
    Permalink to comment#

    Good Article. Love the bookmarklet, very cool.
    Personally I wouldn’t want to sprite all my background images as it would just make maintaining a site problematic. Especially in situations where you might want to change the size of an element and thus the size of the background image – then you would have to rebuild your sprite image AND go through and fix the positioning on many elements. Which brings me to the work around I used on the one site I used this for, just give each item plenty of space so that resizing any given element doesn’t need to effect anything else. (ask.com’s sprite is setup this way, for the most part).

    One thing that I didn’t see mentioned (maybe because everyone already knows it). Is that for rollover items this is kind of a must. Without using some form of sprite technique for rollovers, all too often rollovers don’t work properly the first time a user mouses over them. Unless you preload the graphics there will be a delay before the rollover image appears. Users don’t care to wait around for your half loaded navigation system to finish loading when they go to use it..

  77. Arch Focus
    Permalink to comment#

    Oh yeah, I didn’t read all the comments (only about half), but someone mentioned the fireworks’ PNG8 format and its 4 bit transparency and you asked for more info on this but the responses were not very detailed.

    I prefer to use fireworks PNG8 for transparent images because they will work in virtually all browsers and while you won’t get alpha trans in IE6 they at least degrade nicely.

    I create my image in photoshop and I make sure that any semi trasparent elements are truly semi transparent. Meaning I make sure that shadows have no portion which is more 100% and I amke sure that things which have anti-aliasing first have a clean looking non-anti-aliased version and the anti-aliasing effect is separate and has no portion which is 100% opaque. I do this by breaking things up into layers and then setting the opacity on layers with shadows/anti-aliasing/other semi-transparent effects to 98%. This way I know exactly what will disappear in IE6. Then I open the photoshop file in fireworks and export it as PNG8 with alpha transparency. I tried using some other PNG tools which can convert PNG24s into this format but the results where often very unpredictable and uncontrollable. Fireworks is the only tool which can do this in a precisely manner.

    With this type of PNG8 IE6 will show any pixel which is less than 100% as 0% so it will basically display as a regular PNG8 with 1 bit trans. So all the shadows/anti-aliasing/etc. simply disappear in IE6. So you get some more jagged images with no shadows etc.. But at least you don’t get big gray boxes and you don’t need to use any PNG transparency fixes either. I have tried many PNG trans fixes (maybe even all of them) but generally I have found them all to be problematic and/or unreliable, meaning it may seem to be working fine in IE6 but then I see it on a friends computer with IE6 and it is all half broken for some reason. I also prefer to avoid js for style/appearance and only use it for functionality. So you can see the site fine without java but if you want to use some feature maybe you will need js.

    As far as things looking a little jagged in IE6.. Personally, I couldn’t care less as long as the layout isn’t broken and there aren’t big gray boxes all over.

    A word of warning though: this technique is best used by people who are well versed in photoshop and who have a strong grasp of raster based graphics in general, because without taking deliberate and precise control of transparency levels in your graphics the results may be very unpredictable and ugly.

    A word of advice: I was working with raster graphics for game mods for doom/doom2 and the marathon games back in the 90s and those games only supported 1 bit transparency. Also icons for win95/98 could only have 1 bit trans. If you get right in close and carefully tweak the edge pixels by hand you can create fairly clean looking edges and minimize the jagged appearance of 1 bit trans graphics. But I have yet to see any app that will do a good job of this automatically. If you import an illustrator file in photoshop and turn off anti-aliasing in the in the import options you will get a very nasty looking jagged image but if you spend an hour or two tweaking the edge pixels you can make it look quite clean. Of course semi-transparent or specific background color anti-aliasing will look cleaner still but by combining all of this in a carefully controlled manner we can use semi-transparent PNGs that degrade very nicely in IE6 (i think even 5.5) without messing with javascript fixes or AlphaLoader (which is very slow).

    The problem with most of the PNG fixes are that they mostly depend on JS and AlphaLoader or old VRML features all of which will be more strain on the client system. Yeah sure, no big deal on this system I’m working on now, but the crappy old junker system I use to test IE6 is slowed to a horrible crawl by those fixes and the reason I use that crappy system to test IE6 is that I think it is representative of the type of system that most people who are using IE6 may have.

    You can find other tutorials on using PNG8 with 4 bit alpha trans and you can find a couple other tools that can convert PNG24s to this format, but those tutorials don’t go into the various quirks that you will come up against. To get really good results is not as simple as just converting a graphic, but if you put some thought into it and do some experimentation and use fireworks as oposed to one of the other converter tools you can get splendid results this way. Also much smaller files than PNG24. Some graphics just won’t look nice this way though because of the limited color palette which is further reduced by the 4 bit alpha, large gradient areas for instance.

  78. I freakin love the Chuck Norris quote – good form!

  79. George
    Permalink to comment#

    I’m new to CSS, so please bear with me.

    I can get the background image to load correctly by putting it in a class definition, like this:

    .item-video {
    background-image: url(‘images/video-nav.gif’);
    }

    … but only if I then apply the class to the li element. The gif does not appear if I apply the class to the anchor element. And when I do get the gif to appear when applying the class to the li element, the href link in the anchor does not work.

    I think this is because the li and a HTML elements really don’t have any content… just a background graphic, so I’m a little lost. It seems like in Chris’ “after” example above, he has the Item 1, Item 2, Item 3, etc, text elements in the anchor elements, but what’s creating the actual box around the text and background element for the browser to “see” as a link?

    Any help is much appreciated.

  80. Permalink to comment#

    Sprites are cool but I wanted to have more control about how I create them, I tried an Air App called Tonttu but I can’t export anything from it, if I could it would be perfect.

    Has anyone used it with success or shall I just not bother with it?

  81. Permalink to comment#

    Tonttu worked very well actually. Though, I think Spriteme takes into account your css quite a bit more making it the better option of the two.

  82. Permalink to comment#

    Hi Zander,
    Try spriteme.org straightaway it is very better.

  83. Permalink to comment#

    Great post! I was wondering if it was faster to do something like this, and come to find out, it’s way better and faster! Thanks for the tips!

  84. Permalink to comment#

    Yeah, I always used to wonder about how they work. Very good explanation by the author. Its really good and fast if we can split simply a single image for various objects.

    Best Regards

  85. Permalink to comment#

    I think is good idea, but I hadn’t try it out sometimes!

  86. I never thought quoting Chuck could be so profound.

  87. Permalink to comment#

    Great article,… and a good way to optimize a site.

  88. Dmitriy
    Permalink to comment#

    Good article! What do you think if all images will be in one sprite, and the sprite image will be big (width x height), and used for around 50 elements, won’t that be slow for some browsers?

    Thanks.

  89. I have been heard and even trying to use sprites on my websites but I never taught it can be so global implemented. Thanks for the article. Bookmarked :)

  90. Permalink to comment#

    I don’t know if someone already posted this suggestion but wouldn’t it be faster for the site to load if the buttons would be split into 3 layers: normal background, hover background and button image. You’re loading normal bcg and hover bcg just once(2 HTTP requests) and then button images(5 HTTP requests). That gives 7 HTTP requests and the images should be really small in size.

    What do you think about this idea?

  91. Permalink to comment#

    Good idea, thank you for your interesting article.

  92. Permalink to comment#

    I just heard about sprites from the good folks at welovecss.com. I wanted to use something besides javascript and though this is stretching my capabilities a bit which is good, I love it!

    Thanks for a great informative article.

  93. mkj
    Permalink to comment#

    i was always viewing simlies of facebook and google(1st time i seen there). i was thinking how do they do. :o its pritty easy. :p

  94. igorska
    Permalink to comment#

    It’s a great and helpful article. Thanks for sharing with us.

    All the best.

  95. Permalink to comment#

    I created an application for Mac called Sprite Master Web to help devs to create spritesheets and CSS code automatically.

    You can find it at mobinodo.com/spritemasterweb

  96. Kushal
    Permalink to comment#

    Hi Chris, Finally I got, what exactly CSS sprite means. Thanks!

  97. great revamped article!
    I’ve just taken over a project using sprites extensively. The following tool helped to lessen the pain of updating some icon even in size:

    http://www.spritecow.com

  98. Robert
    Permalink to comment#

    A different way to do this is to just create textNodes or an empty element instead of creating a transparent image. That way you’re only using one image, the spritesheet.

  99. I’d prefer using this method over textnodes, just easier

  100. Chris B
    Permalink to comment#

    Any way to do this using SVGs?

  101. MarkRoot
    Permalink to comment#

    I am looking for something like this, but I also want to position the background image on the right center of the UL LI. The image is not the same width and height as the UL LI i use it in as a background (icon).

    So I would need to use: background-position: right center; but then I cannot use it to position the sprite and it shows the whole sprite img.

  102. Great post! We are using sprites for big directories and they work very good. The most important thing is that it reduces a lot the calls to server – for desktops or mobile – it just shows instantly a raise in the load time. But it is of course if you optimize the whole sprite image. Other than that sprites is the greatest invention from css – in my opinion, ;)

  103. Can’t wait for SVG to be widely supported and optimized for web performance. CSS sprites go a long way for eliminating HTTP requests but nowadays we need our icons in many dimensions for responsive websites and for devices with higher pixel density (Retina). So, vector is the next logical step in evolution.

  104. The site I am working on has recently been suffering from slowish loading, mainly down to my code and images not being as optimised as they could be :)

    I have added a page which needed quite a few images, but wanted to ensure the load speed was not overly affected. Read about sprites a while ago and just by chance a quick search led me here. Wow! Opened my eyes somewhat. I have implemented the technique here PIL Leaflets and it works a treat.

    One slight adaption is I wanted a common background which I have added via css to the containing div, the sprites are applied to the img itself which overlays this. This keeps the main sprite to a minimum size. Over my old methods of working, I reckon its saved 4-6 secs on the load time. I’m sure with some tweaking it can be reduced even further.

    And was quite fun putting it together to boot! Cheers for the article, it was a great help :)

This comment thread is closed. If you have important information to share, you can always contact me.

*May or may not contain any actual "CSS" or "Tricks".