CSS Sprite Best Practices

We’re in the process of converting our web site to use CSS sprites to improve frontend performance. To implement CSS sprites, I’d recommend using SmartSprites. It’s a simple build-time tool that allows you to build your CSS using regular separate background images, annotate the CSS files using CSS comments, then run the tool and have it generate the CSS sprite image files and updated CSS files. It’s an excellent tool.

Unfortunately, due to limitations in the CSS sprite concept, SmartSprites can’t work with just any background image usage you already have. Here are a few pointers to keep in mind when building your CSS, to make sure it’s as spritable as possible.

  1. Don’t use CSS sprites pre-SmartSprites. This may sound obvious, but there are some reasons why you might end up with some CSS sprites before you use SmartSprites. For example, our design firm implemented hover states for UI elements as CSS sprites: the same image has normal and hover states, and a hover event just changes the background alignment. Also, we use YUI widgets, and some of their default styles use CSS sprites.

    The reason SmartSprites doesn’t work on existing CSS sprites is that it ignores your existing background positioning declarations. It assumes you have a single background image, includes that image in the sprite, then positions the sprite to show that one image.

    The workaround I used for this was to split out the smaller CSS sprites into individual images, which are then recombined by SmartSprites into the macro sprites.

  2. Separate out “background properties into “background-image.” SmartSprites requires background-image to be on its own line. It’s not too hard to refactor later, but if you can write the styles this way to begin with, you’ll save some time.
  3. Make sure repeating images are as few pixels as possible in the repeating dimension – preferably 1px. In order to get repeating sprites to tile properly, SmartSprites has to find the lowest common denominator of the image size. For example, if you have a 2px repeating image and a 3px one, it can’t just sprite them together, because then the 2px one would have a 1px empty row. And it can’t just repeat the first pixel of the 2px one, because the pattern might not tile properly. So it needs to create a 6px image, repeat the 2px one 3 times, and the 3px one twice. 6px isn’t too bad, but if you add a few more images of different sizes, it can expand out of control.
  4. Whenever possible, make your background images cover the whole element, not just part of it. Don’t create a vertically-expandable div and style a background image to cover just the top of it – instead, create one div that’s the height of that background image, and style that. Remember, a CSS sprite is a bunch of images concatenated together, so you won’t get blank space below it: you’ll get more images. One way you can get around this is to take advantage of SmartSprites’ ability to organize the images either horizontally or vertically. If you append the images horizontally left-to-right, there won’t be anything below that header image, so you can still style it to cover just the top. One case where this won’t work, though, is in repeating sprites. If you have a horizontally-repeating sprite at the top of an element, then it’s difficult to put it in a sprite, because the only place to put other elements is above or below it, and the below ones will show up in the element.

6 Responses to CSS Sprite Best Practices

  1. Hi Josh,

    Thanks for mentioning SmartSprites and the great tips! I’ve added a reference to this blog entry to SmartSprites website.

    I’ve planned a few improvements to SmartSprites that should address point 2 (http://issues.carrot2.org/browse/SMARTSPRITES-22) and 3 (http://issues.carrot2.org/browse/SMARTSPRITES-39) on your list, but I’ve yet to find some time to implement them… For the time being, the workarounds you suggested are the only way to go.

    If you have any other ideas for features or improvements, feel free to post them on SmartSprites discussion group or file a JIRA issue for me.



  2. Holly says:

    Thanks for putting together this list. The repeating element note is a great explanation. A solution to this that I have seen is to create two additional sprites for repeating elements: one for the x-axis, and one for the y-axis, both 1px in width/height respectively. Your explanation was concise yet informative, and helped me understand the reason sprites expand out of control (and eventually defeat their purpose altogether).

  3. Yekta says:

    For those out there who like myself were wondering how to split out the smaller images from the sprite (from step 1) I’d recommend using ImageMagick

  4. Mobinodo says:

    If you are on mac, you can generate your sprite sheets more easily with Sprite Master (http://www.mobinodo.com/spritemaster).

  5. b9dev says:

    These are not best practices. 1) Using background-image instead of background means sending wasteful CSS to the browser, causing CSS bloat. 2) Repeating images 1px wide or tall cause serious CPU burn on some browsers like older IE – you can actually freeze the browser this way. Always use a repeating size of at least 16 pixels, preferably larger.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: