When you are coding up a brand new site, I think this is a pretty efficient workflow for how to handle CSS Sprites.
- Ignore sprites entirely. Make every background image its own separate image and reference them as such in the CSS.
- When you are reasonably sure the design is “done,” use the SpriteMe bookmarklet to create the sprite. UPDATE: SpriteMe page is dead, but I’ve archived a working version of it here.
- Comment out (not delete) the old background properties in the CSS and add in the new Sprites-based version:
#logo { /* background: url(images/logo.png) no-repeat; */ background: url(images/sprite.png) -10px -579px no-repeat; }
- Don’t worry about the comments bloating your CSS, you should compress your CSS before serving it on live sites anyway which will remove those.
Now if you find yourself needing to update the images inside the sprite, the process can be:
- Update individual images.
- Comment out Sprited CSS background images and uncomment regular background images
- Remake sprite with SpriteMe, replace
- Swap comments again
One of the complaints about working with sprites is that it makes updating images harder. I think this process makes it much easier. I guess an even easier process would be to have a PSD of your sprite so you can update that directly without touching CSS. If you can pull that off, great. I personally feel more organized having individual graphics. SpriteMe also gives you CSS with the locations of all the sprites, so if you needed to change the size of images or add/delete them, you’ll get those new numbers automatically.
If you have your own workflow for working with sprites, please share!
Related: Setting up sprites diagonally is rather clever. The idea is then you can use the sprite as a background image of a larger box without fear of other graphics in the sprite showing up. This is at the cost of a larger sprite file size because of the extra white space.
Re: Editing the sprites. If you anyway have the separate background images, you can easily edit those and insert them into the sprite over the old version, and re-save. Unless you are changing sizes.
“…you should compress your CSS before serving it on live sites anyway.”
In my opinion that’s not what people should do. Serve gZipped files instead and remain viewable. I like that much better from a developer’s viewpoint.
Why not both? Or do you have some evidence to share that that is ineffective? I used to agree in that I liked serving up viewable CSS. This site in particular I thought it was appropriate. But then I just found that CSS is far more typically viewed, when peaking around at other people’s stuff, through a tool like Firebug or Web Inspector where is just doesn’t matter how the formatting of the actual CSS file is done.
Word to that!
The first thing that I do is right-click view page source…
Is there a way to un-compress a HTML/CSS file so it can be readable?
@Tom:
You can copy & paste into here:
http://www.codebeautifier.com/
You could also minify your file to something like style-min.css and still have style.css live.
Compress and gzip if possible. The success of the site is way more important than letting other folk have a readable experience in view source.
Web Inspector would make it readable if the user really need to read the code.
I agree to serve it compressed and gzipped.
Thanks Chris!
As you know, is it better to use diagonal Sprites instead of the generated Sprites of SpriteMe ?
Diagonal sprites would only be used if you were in the circumstance where you needed to be applying background images to areas that were larger than the image itself. If you are in that situation a lot, give it a shot. And definitely read that linked article for the skinny on it.
What I don’t follow about diagonal sprites:
1. container too tall? yeah, solves that. but so would a horizontal sprite.
2. container too wide? yeah, solves that. but so would a vertical sprite.
3. container too tall or too wide. yeah, solves that.
4. container too tall and too wide? does not solve that.
If you already know the problem you’re going to face, you can solve the problem (and save file size) much more easily by going some other route. Personally, I don’t often run into the “too tall or too wide” issue – if something isn’t going to be fixed dimensions, then I don’t necessarily know what either dimension will be: may be too tall and/or too wide, in which case, this wouldn’t help much at all.
So what’s the deal?
I kinda think it does solve that though. If the sprite location is in the upper left of a box for example, that box can be infinitely wide and infinitely tall (to the right and down) without showing another part of an image in that sprite. Of course that depends on the location in the box and the diagonal that you choose. If you wanted to put the sprite in the top right corner, you’d need to reverse the angle of the sprite layout.
mmm… gotcha.
I was not thinking of necessarily placing the image in a corner, though (now that you mention it) that is probably the most common place sprites are used.
okay, all is now well in my world. : )
thanks
Diagonal sprites are interesting, but it’s not just the file size you’re increasing, it’s the amount of memory usage.
http://blog.vlad1.com/2009/06/22/to-sprite-or-not-to-sprite/
“The biggest problem with CSS sprites is memory usage. Unless the sprite image is carefully constructed, you end up with incredible amounts of wasted space. My favourite example is from WHIT TV’s web site, where this image is used as a sprite. Note that this is a 1299×15,000 PNG. It compresses quite well — the actual download size is around 26K — but browsers don’t render compressed image data. When this image is downloaded and decompressed, it will use almost 75MB in memory (1299 * 15000 * 4). If the image didn’t have any alpha transparency, this could be maybe optimized to 1299 * 15000 * 3, though often at the expense of rendering speed. Even then, we’d be talking about 55MB. The vast majority of this image is blank; there is nothing there, no useful content whatsoever. Just loading the main WHIT page will cause your browser’s memory usage to go up by at least 75+MB, just due to that one image.”
Granted the sprite site is pretty obscene, but it illustrates the point.
Very interesting stuff, especially about the 26k image using 75MB of memory.
What about data URI’s? Anyone trying that out yet? I am thinking about it, but want to get more info.
I have some information on that here:
yo, i keep reading about the positives of using data:uri for images. thoughts? if they are that much better, i’ll certainly change over, but i love sprites, and would hate to stop using them.
Nicholas Zakas has some great info on Data URIs:
http://www.nczonline.net/blog/2010/07/06/data-uris-make-css-sprites-obsolete/
http://www.nczonline.net/blog/2009/10/27/data-uris-explained/
@albert,
data:uris are a much better solution, on average. The two articles that Nicholas Zakas mentioned by cancel bubble are worth reading (I think he also has a project which compiles the data URIs for you).
There is no case I can think of where sprites are better than data:uris. This is particularly true if any significant traffic crosses the ocean.
Save one.
jQuery’s ThemeRoller provides the counter example. They generate images for icons and disclosure triangles. You can have as many as 5 or 6 different icon colors. By putting the icons for a single color in a single sprite, you get very efficient CSS.
The thing is that ThemeRoller is designed to use sprites for icons. If you’re just following Chris’ workflow, data uris are probably better choice.
IMHO
This is similar to my own sprite workflow, but I feel the most time-consuming part is dealing with the re-made sprite. Instead of simply adding CSS for the new images, I’m forced to adjust the CSS for every image in the sprite.
I’m tempted to try the Photoshop technique, but while I’d save time updating the sprite, I would certainly lose the loads of time that SpriteMe saves upon sprite creation.
On putting all sprite source images into one PSD, why not just use Smart Objects? Editing would remain in the individual files, yet the final layout for the sprite would be retained.
Of course none of this applies if anything changes size.
I would add to #1:
Each of these separate images should be saved as full-quality 24-bit PNGs, to avoid “double compression” by the sprite generator.
I don’t use sprites that often, but when I do I will be using a workflow like this. Haven’t heard of the SpriteMe bookmarklet before. Thanks for sharing!
I started to use http://lib.coderizer.ee/spritemaker/ for my sprites… really good one.
When using sprites for many elements, you could also consider declaring the sprite image for all the elements that use it in one block. For example –
And then simply use background-position later on for each element. It might save some bytes and makes managing sprited elements a little easier.
Not sure if anyone’s mentioned it, but check out this script: http://codecanyon.net/item/css-auto-sprites/85409 it makes “spriting” a whole lot easier. Very cool
Hey Chris,
Doesn’t that sprite tool add a ton of unneeded white space to the sprite? It looks rather inefficient.
I think it adds about 10px of space between each sprite which is good practice anyway. It does it vertically, so if you have a zillion of them you could probably do better arranging your own grid. However, “speed” is a big part of workflow, so using an automated tool that takes about 30 seconds to use or handcrafting things which may take hours definitely needs to be taken into account.
Consider the diagonal sprite maker that is available in the related article posted above. It largely reduces the height of the sprite by placing the images diagonally.
i always make my own *sprite.psd, as most projects i work on go through many changes/revisions before they ever reach production.
also, this way when the client asks for *all* of my slices (which i am historically terrible keeping up with) i can just hand off the source file, and everyone is happy and full of glee.
also, i have always heard that horizontal sprites load faster, so i generally lay them out with distinct images placed side by side while related images (button states, custom form input bgs, et cetera) are placed vertically.
i also tend to make specific sprites for repeat-x and repeat-y images.
not sure if this is the best, it’s just how i roll, yo.
For generation of sprites, I use SmartSprites (http://csssprites.org/). It generates a sprite image based on comments in the CSS saying which images to change to sprites, and outputs a new stylesheet (with the sprites used). A lot nicer than SpriteMe or similar, IMO. :)
PRESSURE YOUR FAVORITE BROWSER DEV TO IMPLEMENT -MOZ-IMAGE-RECT!!!!!!!!!!!!!!!!!
be carefull with the linked css compressor. it deletes css3 gradients!
I use spriteme quite often, the only problem is that it totally forget about background-position changes on pseudo classes like hover and active…
how do you handle this?
We keep a Fireworks PNG with all the separate elements and gridlines in an img/source folder, in source control. One vertical sprite for icons and other elements that will be displayed horizontally, with safe spacing, and a horizontal one if needed for flexible height elements. That way anyone can modify the sprites safely, and you can get exact positioning info from the FW file.