Menu Search
Jump to the content X X
Smashing Conf New York

We use ad-blockers as well, you know. We gotta keep those servers running though. Did you know that we publish useful books and run friendly conferences — crafted for pros like yourself? E.g. upcoming SmashingConf Barcelona, dedicated to smart front-end techniques and design patterns.

CSS Sprites: Useful Technique, or Potential Nuisance?

Ah, the ubiquitous CSS sprites — one of the few web design techniques that was able to bypass “trend” status almost instantly, planting itself firmly into the category of best practice CSS. Although it didn’t really take off until well after A List Apart explained and endorsed it1, it was discussed as a CSS solution as early as July, 2003 by Petr Stanícek2.

Most web developers today have a fairly strong grasp of this technique, and there have been countless tutorials and articles written on it. In almost every one of those tutorials, the claim is made that designers and developers should be implementing CSS sprites in order to minimize HTTP requests and save valuable kilobytes. This technique has been taken so far that many sites, including Amazon3, now use mega sprites.

Is this much-discussed benefit really worthwhile? Are designers jumping on the CSS sprite bandwagon without a careful consideration of all the factors? In this article, I’m going to discuss some of the pros and cons of using CSS sprites, focusing particularly on the use of “mega” sprites, and why such use of sprites could in many cases be a waste of time.

Browsers Cache All Images Link

One of the benefits given by proponents of the sprite method is the load time of the images (or in the case of mega sprites, the single image). It’s argued that a single GIF image comprising all the necessary image states will be significantly lower in file size than the equivalent images all sliced up. This is true. A single GIF image has only one color table associated with it, whereas each image in the sliced GIF method will have its own color table, adding up the kilobytes. Likewise, a single JPEG or PNG sprite will likely save on file size over the same image sliced-up into multiple images. But is this really such a significant benefit?

By default, image-based browsers will cache all images — whether the images are sprites or not. So, while it is certainly true that bandwidth will be saved with the sprite technique, this only occurs on the initial page load, and the caching will extend to secondary pages that use the same image URLs.

Firefox Cache
The Firefox cache displaying images from amazon.com that the browser cached (type “about:cache” in the address bar in Firefox to view this feature).

When you combine that with the fact that internet speeds are higher on average today than they were when this technique was first expounded upon in 2003-2004, then there may be little reason to use the mega sprite method. And just to be clear, as already mentioned, I’m not saying sprites should never be used; I’m saying they should not be overused to attain limited benefits.

Time Spent Slicing a Design Will Increase Link

Think about how a simple 3-state image button sprite is created: The different states need to be placed next to one another, forming a single image. In your Photoshop mockup (or other software), you don’t have the different states adjacent to each other in that manner; they need to be sliced and combined into a new separate image, outside of the basic website mockup.

If any changes are required for any one of the image states, the entire image needs to be recompiled and resaved. Some developers may not have a problem with this. Maybe they keep their button states separate from the mockup in a raw original, making it easier to access them. But this complicates things, and will never be as simple as slicing a single image and exporting it.

For the minimal benefit of a few kilobytes and server requests saved (which only occurs on initial page load), is the mega sprite method really a practical solution for anything other than a 3-state button?

Time Spent Coding and Maintaining Will Increase Link

After an image is sliced and exported, the trouble doesn’t end there. While button sprites are simple to code into your CSS once you’re accustomed to the process, other kinds of sprites are not so simple.

A single button will usually be a <ul> element that has a set width. If the sprites for the button are separate for each button, it’s simple: The width and height of the <ul> will be the same as the width and height of the list item and anchor, with the sprite aligned accordingly for each state. The position of the sprite is easily calculated based on the height and/or width of each button.

But what about a mega sprite, like the one used by Amazon, mentioned earlier, or the one used by Google4? Can you imagine maintaining such a file, and making changes to the position of the items in the CSS? And what about the initial creation of the CSS code? Far from being a simple button whose state positions are easily calculated, the mega sprite will often require continuous testing and realigning of the image states.

CSS for Google's sprite5
Some of the CSS used to position Google’s sprite image

It’s true that the Amazon sprite saves about 30 or more HTTP requests, and that is definitely a significant improvement in performance. But when that benefit is weighed against the development and maintenance costs, and the caching and internet speed issues are factored in, the decision to go with sprites in the mega format may not be so convincing.

Do Sprites Really Require “Maintenance”? Link

Of course, some may feel that sprites do not cause a major headache for them. In many cases, after a sprite is created and coded, it’s rarely touched again, and isn’t affected by any ongoing website maintenance. If you feel that sprite maintenance won’t be an issue for you, then the best choice may be to use the mega sprite method.

Not Everything Should Be a Background Link

Another reason not to promote the overuse of CSS sprites is that it could cause developers to use background images incorrectly. Experienced developers who consider accessibility in their projects understand that not every image should be a background. Images that convey important content should be implemented through inline images in the XHTML, whereas background images should be reserved for buttons and decorative elements.

Amazon correctly differentiates between content and decoration
Amazon correctly places content images as inline elements, and decorative ones as backgrounds.

Improper Use of Sprites Affects Accessibility Link

Because of the strong emphasis placed on using CSS sprites, some beginning developers intending on saving HTTP requests may incorrectly assume that all sliced images should be placed as backgrounds — even images that convey important information. The results would be a less accessible site, and would limit the potential benefits of the title and alt attributes in the HTML.

So, while CSS sprites in and of themselves are not wrong, and do not cause accessibility problems (in fact, when used correctly, they improve accessibility), the over-promotion of sprites without clearly identifying drawbacks and correct use could hinder the progress the web has made in areas of accessibility and productivity.

What About HTTP Requests? Link

Many will argue6, however (and for good reason) that the most important part of improving a site’s performance is minimizing HTTP requests. It should also be noted that one study conducted showed that 40-60% of daily website visitors come with an empty browser cache7. Is this enough to suggest that mega sprites should be used in all circumstances? Possibly. Especially when you consider how important a user’s first visit to a website is.

YSlow
The YSlow Firefox add-on that analyzes performance shows the number of HTTP requests being made

While it is true that older browsers generally only allowed two simultaneous HTTP connections, Firefox since version 3.0 and Internet Explorer 8 by default allow 6 simultaneous HTTP connections8. This means 6 simultaneous connections per server. To quote Steve Souders:

It’s important to understand that this is on a per server basis. Using multiple domain names, such as 1.mydomain.com, 2.mydomain.com, 3.mydomain.com, etc., allows a web developer to achieve a multiple of the per server connection limit. This works even if all the domain names are CNAMEs to the same IP address.

So, while there could be a benefit to using CSS sprites beyond just button states, in the future, as internet connection speeds increase and newer browser versions make performance improvements, the benefits that come from using mega sprites could become almost irrelevant.

What About Sprite Generators? Link

Another argument in favour of mega sprites is the apparent ease with which sprites can be created using a number of sprite generators9. A detailed discussion and review of such tools is well beyond the scope of this article, so I’ll avoid that here. But from my research of these tools, the help they provide is limited, and maintenance of the sprites will still take a considerable amount of work, which again should be weighed against the benefits.

SpriteMe10

Some tools, like the one by Project Fondue11, offer CSS output options. Steve Souders’ tool SpriteMe12 is another one that offers CSS coding options. SpriteMe will convert an existing website’s background images into a single sprite image (what I’ve been referring to as a “mega” sprite) that you can download and insert into your page with the necessary CSS code. While this tool will assist with the creation of sprites, it doesn’t seem to offer much help in the area of sprite maintenance. Souders’ tool seems to be useless for a website that is redesigned or realigned, and only seems to provide benefit to an existing design that has not yet used the mega sprite method.

CSS Sprite Generator by Project Fondue13

Improvements to current tools could be made, and newer tools could appear in the future. But is it possible, due to some of the drawbacks mentioned above, that developers are focusing a lot of effort on a very minimal gain?

Focus Should be on Multiple Performance Issues Link

As mentioned, the number of HTTP requests is an important factor to consider in website performance. But there are other ways to lower that number, including combining scripts and stylesheets, and using remote locations for library files.

There are also areas outside of HTTP requests that a developer can focus on to improve site performance. These might include GZipping, proper placement of external scripts, optimizing CSS syntax, minifying large JavaScript files, improving Ajax performance, avoiding JavaScript syntax that’s known to cause performance issues, and much more.

YSlow's multiple performance recommendations
YSlow indicates many areas outside of HTTP requests that can improve site performance

If developers take the time to consider all factors in website performance, and weigh the pros and cons correctly, there may be good reason to avoid overusing CSS sprites, and focusing on areas whose performance return is worth the investment.

Conclusion Link

Please don’t misinterpret anything that I’ve said here. Many top bloggers and developers have for years extolled the benefits of using sprites, and in recent years taken those suggestions further in promoting the use of mega sprites — so those opinions should be taken seriously. However, not everyone has the luxury of working in a company that has policies and systems in place that make website maintenance tasks simple and streamlined. Many of us work on our own, or have to inherit projects created by others. In those cases, mega sprites may cause more trouble than they’re worth.

What do you think? Should we reconsider the use of mega sprites in CSS development? Do the statistics in favour of the savings on HTTP requests warrant the use of sprites for all background images? Or have sprites in CSS development evolved from a useful, intuitive and productive technique to a time-consuming nuisance?

Footnotes Link

  1. 1 http://www.alistapart.com/articles/sprites/
  2. 2 http://wellstyled.com/css-nopreload-rollovers.html
  3. 3 http://g-ecx.images-amazon.com/images/G/01/gno/images/orangeBlue/navPackedSprites-US-15._V202471683_.png
  4. 4 http://www.google.com/images/nav_logo7.png
  5. 5 http://www.google.com/images/nav_logo7.png
  6. 6 http://developer.yahoo.com/performance/rules.html
  7. 7 http://yuiblog.com/blog/2007/01/04/performance-research-part-2/
  8. 8 http://www.stevesouders.com/blog/2008/03/20/roundup-on-parallel-connections/
  9. 9 http://www.google.com/search?&q=css+sprite+generator
  10. 10 http://www.spriteme.org/
  11. 11 http://spritegen.website-performance.org/
  12. 12 http://www.stevesouders.com/blog/2009/09/14/spriteme/
  13. 13 http://spritegen.website-performance.org/
SmashingConf New York

Hold on, Tiger! Thank you for reading the article. Did you know that we also publish printed books and run friendly conferences – crafted for pros like you? Like SmashingConf Barcelona, on October 25–26, with smart design patterns and front-end techniques.

↑ Back to top Tweet itShare on Facebook

Louis Lazaris is a freelance web developer and author based in Toronto, Canada. He blogs about front-end code on Impressive Webs and curates Web Tools Weekly, a weekly newsletter for front-end developers.

  1. 1

    “A single button will usually be a element that has a set width.”

    on what planet?

    2
  2. 2

    Had no idea about CSS sprites :-) Ok, I’m not a web designer but thanks for enlighten me.

    0
  3. 3

    You argue that css sprites only save time on the first pageload when there’s no cached data and thus has limited benefit. This is false. If the user has no cached data, that usually means they are newcomers to your website and the first impression is what fundamentally forms their opinion about your website. A fast loading website is extremely important when it comes to the first impression so it shouldn’t be overlooked just because caching will hide any optimization later…

    -4
  4. 4

    I’m sorry but this is the worst article I’ve read on Smashing… You’re turning people off of using a perfectly valid technique using nothing more than opinion. If you’re going to be a skeptic and make a valid argument you need to provide some facts and figures. Every section just seems to end with a loose conjecture as to why sprites are bad but without any numbers or even anecdotal experiences to reinforce the conjecture.

    I use sprites every day. We have set rules for when to use sprites and when to use single images. Backgrounds, visual accents, borders, and icons are all in the sprite. Content or anything that needs to be tagged to be accessible (e.g. product images) are separate files.

    The way to do it right is to stay organized. 1) Use a generator it’s not the devil. OR 2) If you’re going to maintain the code yourself your PSD or SVG graphic should have regions of related content with some directional order and plenty of guides as reference points. For example, the sprite I use most often has the site header, body background, and footer as the upper half of the image. Then the lower half right quadrant contains form buttons going from smallest on the left, to largest on the right, then the various button states going down with default on top, then active, and disabled at the bottom. Then the other quadrant of the sprite has icons, checkbox states, and other backgrounds organized into similar zones. For any group of items I’m only dealing with 1 axis, so all of the toolbar icons have a background position of X -255px and all I need to do is increment X by 24px for each toolbar button.

    As long as you’re organized it’s easy to start at some base line and then with simple math, position your sprite. If new images are added to the sprite, hopefully you’ve organized things in such a way that you have room or can shift existing content in a single axis to make room and therefore limit the number of changes required to the CSS.

    Increasing the browser parallel connections to 6 helps from having just 2, but today’s sites can have 20+ core images and then 20+ more secondary images to download over the course of a visit (not to mention extra CSS files, content images, and JavaScript files). So 6 connections will reduce the load time somewhat, but you will still have delays and still be using up server resources unnecessarily. The way to look at this is by the volume of the traffic on the server. Would you rather have 1,000,000 users making 1 request each for your 70k graphic or 1,000,000 users making 40 requests each for your 90k worth of separate graphics. You can do the math on the bandwidth savings as well, as each request consumes a few more bytes to make.

    Does the bandwidth and CPU cost negate the maintenance cost over time? In fact, the real question to ask is, is there a higher maintenance cost to maintain the sprite versus slicing images and maintaining separate images over time? With a sprite I don’t need to slice and name separate images, come up with a naming convention or deal with name conflicts, or have the program produce generated code for me which may not be maintainable, nor do I have to insure that the n number of new images got checked in to version control or successfully uploaded to the server with the last build, and I’m most likely saving some bytes in the CSS not needing separate listings for background for n number of images. Instead I have ONE image site.png and ONE CSS file to contend with, and again if I use simple math and stay organized, maintenance is a breeze, and at least for me it’s reduced my development time not having to maintain separate images.

    2
  5. 5

    I recently finished up a project in which I used CSS Sprites for two significant parts of the website. I actually find myself on the other end, not using them much at all, but only when I feel the are required. The project needed uneven rollovers, and using the technique that I learned about oh-so-long ago in the A List Apart article, I ended up with some nice menus that will degrade nicely as well.

    I don’t trust “Sprite Generators”, not to say they aren’t good for some people, but I feel they are more trouble than they are worth.

    CSS Sprites can definitely improve accessible design, but I also feel they can easily be overused.

    Thanks for getting my brain going this morning! Your article has been working faster than my coffee!

    1
  6. 6

    Great and very detailed explanation.. I still prefer using sprites on buttons. It makes the loading of the states much faster. I haven’t tried using mega sprites though. Nice!

    0
  7. 7

    Joshua Brown

    March 26, 2010 4:55 am

    I generally use sprites for nav buttons, input buttons, and a few other interactive decorations. This technique has drastically improved my coding time, I find that maintenance is easier, and I just think it’s more elegant than using separate images.

    0
  8. 8

    I’m a sprite lover and always use it with care. I think it could be a nuisance since the sprite first made is like the google/amazon. But when I need to do a “mega sprite” (like you said) I try to put every image or state of buttons organized from top-left to right (or bottom), that assures me no need to recalculate background-position for each sprite. Let’s call it “re-sprite”. lol

    Amazing article!

    0
  9. 9

    Come again? Do you use buttons that change width? I cant imagine that looks very good except for using fancy effects that are unnecessary.

    0
  10. 10

    NIels Matthijs

    March 26, 2010 5:04 am

    Biggest problem with sprites is that pixel formats just don’t go well together with flexible formats. And I’m not even talking about ems, even distances in a fixed design are prone to change.

    What’s lacking in the current specs is to only show a certain cut-out of a picture. Current implementations of css sprites require you to hide all the other elements outside the box. Only when we can control what part of an image to show through css, css sprites will start showing their real value.

    Until then, bad practice except from some very controlled situations (icons with no text for example, which will always have the same width).

    0
  11. 11

    Great article that opens up a discussion and make us think about it, love it !

    0
  12. 12

    Geoff Jackson

    March 26, 2010 5:05 am

    I’m no designer by any means but I recently just did my first piece of work using sprites (http://www.clubnetsearchmarketing.co.uk) scroll down to see the SEO, PPC and Social Media buttons and hover the mouse over them.

    I’m quite pleased with the outcome although I can imagine when using this method throughout a whole website, it could take ages :/

    Feedback appreciated though :p Heh

    0
  13. 13

    Lennard Schutter

    March 26, 2010 5:10 am

    Actually all of my buttons have a variable width. Using slider buttons it isn’t that hard to do. What would you do if you have a button with the text: “Click here to order this product”? Make a seperate image for it?

    I don’t agree that different widths in buttons are ugly at all, i even think it’s more ugly to have lot’s of unused space inside your button.

    I know it’s easy to make a fancy button with CSS3, but our MS friends don’t support that, so i use images to at least get some design in my buttons.

    1
  14. 14

    Multilingual website?

    6
  15. 15

    I use Image Sprites for navigation buttons. I create a PSD file with the different states in it and by simply changing the text layer I find it pretty easy to maintain. I never used a “mega sprite” ’cause I find it hard to maintain. If you use a image sprite for each button you can also combine CSS statements.

    Here’s an article I wrote: http://andrislinz.ch/how-to-use-image-sprites-for-navigation-menu

    0
  16. 16

    It didnt copy the part i was referencing…. the ul portion.

    0
  17. 17

    I do use sprites in targeted areas with great benefit in terms of load times, etc. I have written my own java code to build the sprite and css files needed.

    However, I have for a long time wished that http supported retrieval of resources within a zip. In other words:

    < img src=”allMyIcons.zip!big/edit.png” >
    < img src=”allMyIcons.zip!big/delete.png” >
    < img src=”allMyIcons.zip!small/help.png” >

    First image triggers the “allMyIcons.zip” to be downloaded, then pulls out and displays “bigIcons/edit.png” from within that zip. Then the rest just pull the image out of the cached zip.

    This would not save the browser the rendering time benefits of sprites, but it would definitely address the multiple http request issue. And it would be a gigantic time saver on the web-dev side in terms of avoiding having to maintain a sprite file and coordinate pixel positions. I could imagine web platforms rapidly baking this in so that it is automatic.

    1
  18. 18

    If you’re manually generating sprites, you’re doing it wrong. Look, we’re in the year 2010. You shouldn’t have to calculate pixels on a custom sprite. That’s a serious misuse of time. What Amazon probably does is generate these sprites by CODE (ie. the 21st century method). I’ve written an article in the past on how to generate sprites in C# (http://weblogs.asp.net/zowens/archive/2008/04/27/asp-net-mvc-css-sprite.aspx). In my implementation, you just add an image to an images folder, use pre-defined CSS and the caclulation of the position and the generation of the sprite is just taken care of. That’s how it SHOULD be.

    So, to recap, I could not disagree with some of your points more. CSS sprites are beneficial to reducing HTTP requests. Think about it. The average site has OVER 6 images on a given page. Your argument about concurrent connections doesn’t really hold. A site usually has at least a single Javascript file, the page itself, CSS file, images… the list goes on. You want to be stingy with these connections. People have documented significant performance improvements with CSS sprites. Just because we now has 6 concurrent connections on a browser doesn’t mean we can throw out one of the best optimizations that has saved a LOT of bandwidth. I’m going to keep using “mega-sprites” because I’ve seen significant improvmenets.

    1
  19. 19

    Rene Schmidt

    March 26, 2010 5:35 am

    Sprites are a pain in the a**… But you can drastically improve loading times. It can make a huge difference loading 1 file instead of 30. However I would recommend sprites only for sites with lots of visits.

    0
  20. 20

    Nice article, but I have to disagree with the last bold statement.
    Using mega sprites ARE worth the effort!

    But of course you have to adjust your photoshop workflow in order to cleanly maintain the contents within your PSD file.

    Using a clear layer naming/grouping, grids and guides it’s very easy to maintain a sprite that contains a couple douzend graphics.+

    @jlarson: I like the idea, but: This means you have to load an applet in the browser right? I guess the time and performance it takes to start the JVM will exceed the additional loading time of more HTTP requests by far. And not every browser supports Java.

    0

↑ Back to top