Skip to: Navigation | Content | Sidebar | Footer

Weblog Entry

Sprite Optimization

January 27, 2009

Maybe I haven’t been paying close enough attention, but over the past few years an interesting variation of CSS Sprites has been getting a lot of play on large web sites that serve millions of users.

Amazon's Sprites

I stumbled over one of these on Amazon and posted an image here last week, but the comments quickly pointed out that this was far from a unique case. Google, Yahoo, and Apple are also doing similar, and those are just the ones I’ve found so far. Yahoo even documents the practice on their Developer Network and the Flickr code blog.

The problem is making a site with multiple UI elements load quickly. There’s a lot of overhead if your design requires dozens of UI images and icons and the like. File size isn’t the only factor, each image is called with a separate HTTP request, and the more of those you have the longer your site takes to load. At Yahoo and Google traffic levels, it’s vitally important to think about how many million users a day a site is losing to long load times.

The solution? Cram as many UI images as possible into a single image, then use selective CSS to clip and only show the relevant part of the image:

Andy King has written up a great how-to guide on implementing sprites this way. He does warn that the method isn’t without its issues — some devices (the iPhone being the most notable) apply the sprites in a memory-intensive way that slows the device to a crawl.

I also wonder about the pop-in effect; when your entire UI is in one or two larger images that take a second or so to load, the site will render without images for that brief time then pop in all the images at once. This reminds me a bit of the FOUC of old, but in a slightly less jarring way. Probably a necessary evil in this case.

But the question I’ve had on my mind is whether I should start doing this myself. Should all the sites I build use Sprites this way from now on?

I’ve started playing around with this all-in-one approach for UI images, and I’m finding it quick going and fairly simple to do. From Photoshop, I crop my source images and prepare to save, but rather than export to a JPG / GIF / PNG I’ll instead take a flattened version of each image and place it in a new document that becomes the master, saving out the entire thing to an optimized image. (And if I go with PNG, it’s worth also running a non-Adobe PNG compression tool against it, something like Pngcrush or PngThing.)

Planning for repeating images is a bit trickier, but I think the MobileMe example serves as a guide. Have one image per row, leave room between each, and have the repeating bits span the entire master image width rather than the smaller 1 pixel strip you might traditionally have saved out. The extra overhead will compress fairly well, and it seems fairly certain that the fewer HTTP requests will more than make up for it.

So, back to the question at hand, should I be building sites this way? I think the answer is: sort of, yes.

It does require more work. Applying the section of the master sprite image you want to show up takes time. And you really need to carefully plan out that master sprite image to ensure the wrong slice doesn’t show through on text-resize or in unplanned text wrapping situations. I don’t see every site benefitting enough to justify the time overhead.

Of course, the maintenance is also easier; need to change the colour of a UI element? Just edit the master and re-save one image. Done. Need to add more images? Make the master a little larger and drop ‘em in. Done.

Web applications where a quick-loading and responsive UI are essential seem like the perfect fit. Sites with a common set of design elements that are used globally across the site might also benefit.

But I doubt most sites will require you to go as far as the every-image-in-one like the MobileMe example; a lighter approach of, say, combining all the icons into one image file like Yahoo is likely good enough most of the time. And simple wins like taking a box with rounded corners which traditionally would have been three separate images (one for the top, repeating middle, and bottom) and combining those three into one is fairly trivial to pull off.

The main change I expect is that I’ll likely look for ways of reducing the overall number of images I save out for each site in the future. If I can see a quick way of combining a half dozen into one, I’ll do it. If I can’t, oh well. If I end up with 12 images instead of 20, that’s probably optimized enough for the majority of sites I’ll build.

January 27, 16h

I find it a pain in the ass to do it by hand – if you have to resize some of the sprites it throws off the co-ordinates of all the others, and you then have to figure out what their new co-ordinates are and change them in the CSS. It’s even worse when you inherit the sprite and have to figure out what’s what.

Google Web Toolkit has a neat auto-spriting feature that takes all your separate images and compiles them into a sprite (well, a couple of sprites, for horizontal and vertical repeating images). Of course, then you have to buy into the whole GWT platform.

Dave S. says:
January 27, 16h

Good point; I assumed it’d be easier because new ones cand just be tacked on to the end of the image, but I didn’t really think about resizing.

There are other automated tools out there too, eg. or – but I haven’t really looked into them.

January 27, 16h

There are open source packages that create sprites too. SmartSprites is a good one. You create CSS with a few conventions, and it packages that up into a new CSS file and a sprite.

If you have a build step in your deployment, it’s pretty easy to slip it in. Added advantage is you can develop with individual images and the source CSS, then deploy the streamlined version.

Also, it runs on your computers, so you don’t have to buy in to GWT or whatever.

January 27, 16h

Great write up Dave. I’ve been thinking about sprites off and on for the past few years… I’ve decided I’m on the fence with sprites…

You said:
” Just edit the master and re-save one image.”

This sounds good, but…

“…instead take a flattened version of each image and place it in a new document that becomes the master”

…if the master is a compilation of flattened images, then it requires more work in that you have to grab your comp, tweak that, then crop, flatten and import into the new master. I also second what Cameron is saying about having to re-tweak coordinates…

Of course, I say all this and I don’t work on sites that get millions of page views. If I did, I’m sure I’d use this solution.

Dave S. says:
January 27, 16h

@Noah Stokes - you can of course create the master any way you want.

But given the way I design it’s easier for me to flatten each out first before combining. If I have one element spread across ten images, and changing the colour of that element requires tweaking ten layers, I’d rather tweak ten layers once and flatten+recombine, then tweak ten layers x ten images.

January 27, 17h


Also, if you happen to use Photoshop, you could just use smart objects in your combined file. Then, when you change any of the original images, the smart object automatically updates and you don’t have to re-copy it over to your combined one. You can just flatten and/or export the compilation as a flattened filetype, then run any optimizations you want on that exported image and you’re good to go.

Cam C. says:
January 27, 17h

I’ve moved away from doing massive numbers of images in one sprite; I actually experimented with it a few years ago (shortly after your original article, I think) on a couple large web apps, and ran into some of the problems other comments mentioned. I also noticed diminishing returns on file compression once you start combining huge numbers of dissimilar graphics.

Speaking of compression, as I recall, another issue that pops up when you have massive numbers of images in one sprite is that your arrangement of them can drastically change the amount of compression… I’m sure this has been written up somewhere, but if you have a large number of buttons it seems to be more economical (particularly with GIF, less so with 8-bit PNG) to put them in a long vertical file. The simple explanation I read way back when was that having a large number of vertical lines (whitespace between graphics for example) in a GIF balloons the compression due to some quirk of LZW… mind you, even bad compression of repetitive elements is better than none, ie. not using sprites at all.

I tend to make smaller groups of sprites now, grouped by functionality or placement in the layout… one file for buttons, one for icons, one for image replacement text, etc.

Alex says:
January 27, 17h

Here’s another sprite generator that may be of interest to readers:

Matt B. says:
January 27, 18h

I sure hope these sites, especially MobileMe, have written guides for using their sprites. it would be horrible to be constantly asking “Do I want the one at 0 -125px or the one at 0 -135px?”.

Steve says:
January 27, 18h

I’ve been doing application programming that way for years when the application needed some sort of graphic feedback to the user’s attempt to control a dial or knob or whatever. I was surprised to discover the same concept being discussed for use in web pages when I was surfing the net a while back. Heck… why not?

Its essentially the same concept of menus based on sliding-doors.

Haven’t bothered to try it for web pages yet…

Nathan says:
January 27, 18h

I find that I use sprites for parts of the page that seem to be related (like a nav, etc), but I don’t like including every image into one master image. If it’s already a large image, I will leave it out alone.

It’s more of an art than a science to me.

January 27, 21h

It’s not as simple as ‘throw all the images into one image’. One image probably isn’t your best bet, as browsers can download your images in parallel. Using multiple sub-domains for the images can have a dramatic effect.

You can also get into issues with color maps. If you have two images that can both get by with 8-bit color maps, that doesn’t mean you can put them into one new image with an 8-bit color map (you need the union of each image’s color map to fit in 8 bits). Going form an 8-bit png to a 24 or 32-bit png can have a big impact on your file size. So, very often, you’ll want to group images with similar colors to keep file size lower.

Also, if you have EVERY image, you’re probably sending too much info on your home page. Case by case - but generally speaking, if you have a dominant landing page, it’s worth tuning a version of the CSS / JS / Images just for it to make your first impression as snappy as possible.

January 28, 01h

This is very effective, I have used the general idea in the past, however I’m not so sure it works with fluid sites. The MobileMe example gets around the width issue but what about height when text scales?

I generally take each interface element on it’s merits and group images in that way.

Riddle says:
January 28, 01h

Maybe I’m oldschool, but I can’t sleep if elements on my site doesn’t scale vertically, when text size increases. I don’t see how it could be achieved with buttons / icons made like this.

Matt says:
January 28, 02h

The post mentions:

“it’s worth also running a non-Adobe PNG compression tool against it”

- I was wondering why? I’ve never used other png compressors before, are the file sizes noticeably better? Suppose I’ll get hold of pngthing and try it out..

Jack says:
January 28, 03h

I would be very keen on using this method if it wasn’t for fear of scalability. Just the thought of it not working or aligning badly is enough to put me off, despite it’s good points.

Rob says:
January 28, 05h

“At Yahoo and Google traffic levels, it’s vitally important to think about how many million users a day a site is losing to long load times.”

It’s not just at their traffic levels that you can lose users. A slow site with 100 daily users will also lose a percentage due to slow load times. No site owner wants to lose users.

I wrote about this very topic a few weeks ago:

ncus says:
January 28, 06h

I have been using sprites since I know about it. I have experience on creating graphics sprites for games, so this method is not surprisingly difficult.

I always group my sprites into extension: JPG, and PNG 8bit. Never use GIF, PNG is smaller than GIF. This purpose is to separate looseness image with index color image.

Thomas Subera says:
January 28, 06h

Using sprites quickly showed you need about 5 different sprite images. Our designers love making patterns which are repeated vertically or horizontally.

So you need a sprite with all the horizontally repeated images with 1px width and an enormous height (adding the images together). And a similar sprite for all vertical repeated images.

Then there are the images you need to align on top or bottom, which i pop together in a sprite side by side. Of course there are also images you want to align left or right, that ones are in a different sprite stacked.

The last sprite i use for icons likewise google does for their side packed in the smallest possible way.

I tried the tools told here for sprites but had problems with all this 5 sprite variants. And since i don’t like gaps which are not needed, we build our own little java application where you can decide which way you need the images aligned. It saves the image and also give you a css output with all the background positions.

That way it’s always possible to add or remove images without much work.

Pete B says:
January 28, 06h

Firebug makes working with sprites a lot easier.

It’s still a bit fiddly, but at least with the firebug console you can change the background-position values with your cursor and see the results in live view.

January 28, 07h

I tried using PNG Thing on an image and didn’t see any change. It was a small 1x50 graphic saved with PNG-24. Save for Web in Photoshop got it down to 160bytes, which is only slightly above GIF which came in at 150bytes.

Annoyingly, Finder can’t seem to tell you how big a file really is if it’s smaller than 4KB for some reason.

January 28, 07h

It’s quite a task to get it vertically and horizontally right. It may mean to make compromises here and there. You cannot place all images in one, when you for example need a middle image which scales on both axis.

In the qooxdoo JS framework ( I was involved in we have a json-like configuration where one defines which source images to combine to a larger one. The tool chain then automatically created a combined image and a json data stucture with offsets to be used via JS. The application developer works with the original path names in the application but automatically make use of the combined images when they are available. It is quite useful to automate it this way. Though it does not work with a simple CSS/HTML site where the interface is not rendered via JS. (Ok, maybe some kind of CSS rewrite can do something like this too.)

You may like to see an example of a Button in qooxdoo here: The Button is scalable in both directions. Try to increase the font size and reload (no dynamic reaction for now).

January 28, 07h

For the re-sizing implications alone i’ve steered clear of this method for whole sites though i’ve been using it for ages for hover effect items.

I always thought that fewer http requests was obviously a good thing but if your large image got quite sizable then surely the benefits would be lost too?

January 28, 08h

Regarding resizing issues. I’ve started using sprites selectively and my method for resizing is to simply give the graphic some extra vertical height. This works for gradients well enough. So if I have a menu item that’s normally 50px high, I’ll take that 50px high gradient, make the canvas 100px or so, and then repeat the top pixel to fill the extra 50px. If that doesn’t work, just give some space between each graphic to allow for resizing.

John says:
January 28, 08h

A little off-topic, but they reminded me of sticker sheets. Quirky promotional giveaway, perhaps?

Gonzo says:
January 28, 09h

Sprites are great tool when used wisely (as is any tool). When reading the comments I see many people concerned about what will happen when the text is resized. Well, most modern browsers do page zoom by default and most users wont change that. A few pixels extra padding between the images wont hurt either.

There are places where sprites are not applicable - we often use sliding doors for bigger blocks and the image becomes big enough to be combined with other images.

Also, some people suggest using the data: protocol to embed the images into the css, but this will have negative effect if one image is used more the once, or if the images are big. Remember, the image data is base64 encoded, so it adds 30% to 50% to the actual file size.

About image optimization, read Stoyan Stefanov’s articles in YUI blog:

Dave S. says:
January 28, 09h

@Dave Joyce - “I tried using PNG Thing on an image and didn’t see any change. It was a small 1x50 graphic saved with PNG-24.”

Well, you’re not going to see a ton of saving on an image that small. Try something in the 500x500 range perhaps. I’ve crushed 16k down to 12k, which yes, was around the same size as an equivalent GIF, but the GIF was 64 colours and the PNG was 24-bit.

@everyone worried about scaling - with a bit of clever coding, you absolutely can get these scaling vertically. MobileMe is probably a bad example of this, but see Dave Joyce’s comment (#24) or the original post’s example of a box with rounded corners for a few ideas.

Both horizontal and vertical at once might be a bit trickier, granted.

January 28, 10h

I actually put together a 10 minute video explaining how to implement CSS Sprites for hover effect reasons.

This is probably is a no brainer to the mezzoblue visitors, but for newbies or beginners trying to wrap their heads around CSS in general, but to use sprites I created this video: - How to use CSS Image Sprites in 10 Minutes!

Future videos will be done slower, have better explanations, etc… but this was my first video so cut me some slack lol :)

January 28, 10h

I find it MUCH easier to manage this sort of thing with Illustrator (as opposed to say Photoshop). But I’m funny that way. I use AI for almost all of my design work now.

thinsoldier says:
January 28, 14h

Some of the problems would be solved if they updated css to cover the sprite technique and make it work more like actual sprites on old game systems like the N.E.S. (and then of course for browsers to actually support it)

We wouldn’t need to “Have one image per row” or “leave room between each” or “have the repeating bits span the entire master image”

Instead we’d write some “variables”(or something) in css to indicate a range within the image that should be treated as if it were it’s own image file. The browser would basically copy/paste those areas of the image into memory as separate images. Then there would be no worries about undesired areas of the master image showing up in the wrong place.

Alternatively, we could maybe save such images in a single special zip file that the browser would unpack into separate files and make accessible to to us in a special way:

background: sprite(images/;

Gonzo says:
January 29, 03h

@thinsoldier - your last suggestion looks very similar to the way Mozilla works with the chrome: scheme, where things like XUL files, css, javascripts, etc. are packed al together in a jar file.

After a quick search the jar: URI scheme appeared, I knew there was something like this.

Well, another idea to play with in the lab ;-)

giuliano says:
January 29, 07h


try this website for additional image size reduction without losing quality after using the photoshop exporting tools:

Keith says:
January 29, 09h

Great Article! As a new designer I’ve found sprites to be a lengthy and sometimes frustrating process. I never even thought to search for a generator. Thanks for the suggestions.

Dan Gayle says:
January 29, 11h

I love ImageOptim for mac to compress my images. It’s basically a wrapper of all of the freely available jpeg/gif/png image optimization routines.

As to sprites, getting them to all line up and play nicely is always the hardest part. Or if you use any sort of drop shadow. Those always tend to get cut off :(

I’ve always admired the Apple sprite though. Not too many people are going to make all 4 a:pseudoselector variants for a single image. I don’t even think that I would know how.

January 30, 01h

It’s funny that you mention the Yahoo Developer Network…
I have been trying to get as creative as possible with use of sprites over the years to minimize HTTP requests. As a Linux user, I have plenty of powerful command-line tools to assist in compression and optimization. However, Yahoo themselves have put out a web application for this very purpose that is greatly overlooked and underused, (, which Yahoo themselves seem to not promote much.

Your fellow Canadian (ex-pat),
Akiva Levy,

Timothy says:
January 30, 11h

I’m a big fan of sprites. You don’t get that annoying lag when an image needs to be loaded and you don’t see it for a split second.

Birgit says:
January 30, 13h

hadn’t noticed that before…

talking about http requests in big websites, it certainly is a good idea to do.

but on second thought, a lot of the graphics we use are small icons that indicate the type of a link with unpredictable length (e.g. pdf links, external links, etc). this would result in having to use big spaces between the icons in the graphics, resulting in big file sizes. got any better idea?

January 30, 14h

To make Sprites brain dead simple in Ruby on Rails I created a plugin called ImageBundle that creates sprites on the fly.

You can find an example at It contains links to the documentation and the source (which is available from github).

Gerben says:
January 31, 10h

Just a warning for everyone using this technique. Page-zoom in Firefox sometimes shows a line of pixels of a neighboring sprite.

For example. When going to a google result page and zooming to 110% there are three gray lines at the bottom right. A was wandering what these were. After some checking it seems the google logo image also contained other UI elements.

I’m not sure if it’s a Firefox (Mac) only problem, or that other browser have the same problem.

So when using this technique be sure to add some space between the sprites.

February 02, 13h

I’ve been using this method for a while but only in certain situations. Primarily for website navigation where I might use images instead of selectable text, and the negative margin technique to kick the link text out. I mainly did this because with navigation styling that uses images, sometimes there’s that split second where the hover image doesn’t appear immediately, regardless of how well you’ve optimized your images for the web.

I’m a little hesitant to jump into it for everything but I’m glad Gerben pointed out the page-zoom issue for Firefox. I have a habit of adding some “safe space” between my sprites regardless. I guess as a failsafe.

Regardless, this is a fantastic technique. CSS background positioning is one of my favorite methods and I’ve been using it a lot more for recent endeavors and experiments. It’s nearly bulletproof from all the examples I’ve seen and put into motion.

February 03, 08h

“File size isn’t the only factor, each image is called with a separate HTTP request, and the more of those you have the longer your site takes to load”

This is just unnecessary optimization. Graphic files are usually static, and the HTTP server can get a Content-Length for them so you’ll usually have all of your images pipelined through the same persistent HTTP connection.

Assuming of course that your graphic files weren’t cached anyway. This is actually a reason NOT to use sprites; if you were to change one portion of the image, the whole collection would be invalidated in cache, and everyone would have to download it again.

That isn’t to say it isn’t a valid technique, but I believe the benefits from CSS Sprites in webpages come from rollovers, and when you need to swap one image out with another quickly. It takes more work to swap an image than it does to change a cropping view of the same image.

It’s very dangerous to have a rule of “use sprites always”. Know what you’re doing, and you’ll avoid pitfalls.

Billee D. says:
February 03, 17h

I think that having several sprites broken up into groups of functionality or sections is fine. You end up with about 10-15 images on a canvas and it does kind of alleviate some of the “pop-in” effect you mentioned. I usually break things up into items for navigation (cold, warm, hot states), forms, widgets/boxes, and some times other tertiary items like bullets and lines. This seems to provide the most flexibility for me.

I’m interested to read that link you mention about the iPhone issues. iPhone is becoming a more prominent word on my lips these days. Great discussion! :-)

Theo Skye says:
February 04, 08h

Also, for cheap (albeit limited) hover effects, don’t forget about the easy option of simply changing the background color of an element containing an image with some transparency. For example, a GIF or PNG with some transparent pixels will naturally reveal the background color of its parent elements wherever it has transparency. So instead of switching out an *image* on hover–thus requiring two images (or a larger sprite)–you can just change a BG color on hover.

You can also create some interesting effects by layering multiple images (or the same image) that contain some transparency and changing their positions on hover or some other user input.

M T says:
February 06, 01h

Does anyone know how google looks at sprites in regards to search engine optimisation? Will it push a site higher up in the rankings, or lower it? Are they compatible with all types of browsers and mobile phones?

February 17, 00h

I wouldn’t go out of my way to create a sprite for the entire website. That simply is too much effort for very little return.

That said, sprites are an absolute must for:

1. Websites that use menu images
2. Web application interfaces (think FCKeditor)
3. High traffic websites where speed of content delivery and bandwidth is essential (if your website is still running on a shared server, then no, you do not need to do this yet)


February 17, 13h

MobileMe’s sprites are expressly designed to scale horizontally, not vertically. We don’t use boxes, but we do use buttons (and lots of them in various states: default, focus, active, disabled) and a button size that’s capable of the text scaling up +3 settings.

@Cameron: the key with such huge sprites is making sure they’re documented very thoroughly, so that you can just look it up in a PDF and have all the information and coordinates right there by your side.

February 19, 08h

I agree with Dennison. If a site isn’t going to have much traffic (the majority of the brochureware I do for local companies), I try to avoid creating one sprite map.

But you should still combine normal+hover images, so there is no delay. I’ve made an easy to use PhotoShop script to combine two images that I use all the time along with a script that extends the bottom pixel 50 pixels which is great for background text based navigational elements that *might* have two or more lines instead of just one line. With many of the CMS driven sites I design for, there’s no way to tell how much text is going to be in the menu name.

Vagelis says:
February 22, 15h

I was using this technique for quite sometime, and I found in recent times it is by far the best solution too for almost all kinds of designs.
Great article loved the MobileMe bit, never noticed they took it a step forward! Thanks !

Rob C says:
February 23, 01h

Hi Dave,

I just so happen to come across your post searching for something else, but I’m glad I did. This to me, imho is a really snazzy technique. Thanks!

@Bryan Kohlmeier
Thanks for the video!. I actually implemented it on a site that I am building. I started with a simple menu that gives the impression of a ‘colored arrow’ on mouse over.

Overall I like this style of design due to the efficiency it can provide. Someone above had mentioned about ‘extra work for them’ to get it configured, but all I can say is when was it about what ‘you’, as a webmaster, had to do and not about the end users? Shame on you for that one!

Now, I hope the site provides followups, because I like what I am reading.



February 23, 08h

Does anyone know how google looks at sprites in regards to SEO? Will it push a site higher up in the rankings?

and i do not think it is compatible with mobile phones?

February 23, 08h

@Jamie Hill quoted: “This is very effective, I have used the general idea in the past, however I’m not so sure it works with fluid sites. The MobileMe example gets around the width issue but what about height when text scales?”

My thoughts on how to achieve this would be to have your repeating graphic faded with a solid color below it. Have that in the actual sprite, do not use background-color because of course we know that will not work as the image will cover the background color. So in the sprite you will just have to be sure to create enough of a buffer with that solid color. On a header for example, I wouldn’t suspect that anyone would be increasing their font size to 200px or anything to crazy, so the repeating image does not need to be super long on the sprite. I think that would work.

February 26, 01h

I’m confused.

The techniques discussed here sound well thought out, but as Philihp Busby (#41) suggests, is there actually any performance benefit in using sprites for anything other than rollovers?

Justus Romijn says:
March 04, 06h

I agree with some posts that the most important benefit is the avoidance of flickering menu’s. And furthermore, grouping certain related images to one sprite is also more logical and keeps your web folders nice and tidy :)

For performance issues, I find multiple interpretations of less http-requests, so I don’t have an idea of whether sprites are an improvement there.

But I can recall something of building sprites with a fixed size(in pixels): 1x1, 2x2, 4x4, 8x8, 16x16, 32x32 etcetera. A PC loads these formats better than something like 215x38, but I’m not totally sure about it. Can anyone shed light on this theory?

March 09, 19h

I have used the method described here, and if you’re using Photoshop’s smart objects, it’s really easy to save a psd that has all the ‘cuts’ while still able to be edited afterwards. It’s really not that much more effort than making the actual cuts themselves.

No one likes flickering loaded images. I think sprites are a must must must.

I found using one large image for large, high traffic sites makes editing and maintaining images easier to deal with. If not ONE large image, at least a few separated out in groups of items that are related to each other (like nav, forms etc) Or separating between different mattes if the images are transparent png/gif. Rather than updating multiple images, it’s just one, and if I do need to be sending images to someone or to copy files there are fewer to worry about :)