OK, CSS sprite tools exist. I'm pretty confident I actually made the very first one
But they break from time to time (like mine currently). And then the command line is cool (as opposed to scary) and oh-so-quick. And imagemagick is cool and oh-so-powerful. So let's see how we can create CSS sprites from the command line alone.
Creating the image
Starting with a list of separate image files:
$ ls 1.png 2.gif dot.png phoney.gif tw.gif
- 1.png
- 2.gif
- dot.png
- phoney.gif
- tw.gif
Creating the sprite:
$ convert *png *gif -append result/result-sprite.png
Yes, that's all! The result:
![]()
What?
So the imagemagick command is generally something like:
$ convert image1.png image2.png image3.png -append result/result-sprite.png
But we can also replace the list of images with *s:
$ convert * -append result-sprite.png
Or as in the previous case, limiting to *.gif and *.png.
How about a horizontal sprite? All it takes is changing -append to +append:
$ convert *png *gif +append result/result-sprite-horizon.png
The result:
![]()
Also note how the source images can be any format - GIF, PNG, JPEG and the result is PNG. Actually I'd recommend always trying PNG8 first:
$ convert *png *gif -append PNG8:result/result-sprite-horizon.png
CSS positions
Now since this is all hand-made there's no auto-generation of CSS. But it's still pretty straightforward. Take the vertical sprite:
![]()
All images will have background-position-x of 0px, so that's easy.
The first image will also have Y-position 0px. It also happens to be 16x16 pixels. So it's:
.first { width: 16px; height: 16px; background: url(result/result-sprite.png) 0 0; }
... where 0 0 position is redundant and can be omitted.
The second image is also 16x16, that's convenient. Its X is 0 and its Y is the height of the previous image (16px) with a minus in front. So:
.secondo { width: 16px; height: 16px; background: url(result/result-sprite.png) 0 -16px; }
And so on. Y position of an image is Y of the previous + the height of the previous.
You can use the handy-dandy test page to play around with this (or any other) sprite.
But.. but... figuring out dimensions by keeping track of heights? You kiddin' me?
Imagemagick to the rescue. `identify` gives you the basic image info:
$ identify 1.png 1.png PNG 16x16 16x16+0+0 DirectClass 8-bit 260b
`identify` also has a `-format` option and supports *. So getting all the info in a neat form is easy:
$ identify -format "%g - %f\n" * 16x16+0+0 - 1.png 16x16+0+0 - 2.gif 6x6+0+0 - dot.png 10x16+0+0 - phoney.gif 16x16+0+0 - tw.gif
%f is filename and %g is geometry.
\n is a new line as you would expect and sometimes - is just a -.
So if you want to figure out the Y position of the fifth element, well, it's the sum of the heights of the previous: 16+16+6+16
.last { width: 16px; height: 16px; background: url(result-sprite.png) 0 -54px }
Some complicated math! 'scuse me while I ask my second grader if she can handle it
And some smushing
Imagemagick doesn't write optimal PNGs. So some optimization is due. You can do it yourself with pngout, optipng, etc. Or use web-based tools such as smush.it (you're welcome!) or punypng.com. (psst - how bout a glimpse of the past)
Or how about.... smush.it on the command line:
$ curl http://www.smushit.com/ysmush.it/ws.php
?img=http://www.phpied.com/files/sprt/result/result-sprite.png
Result is JSON:
{"src":"http:\/\/www.phpied.com\/files\/sprt\/result\/result-sprite.png",
"src_size":1759,
"dest":"http:\/\/smushit.zenfs.com\/results\/5a737623\/smush\/%2Ffiles%2Fsprt%2Fresult%2Fresult-sprite.png",
"dest_size":1052,
"percent":"40.19",
"id":""}
Oh looky, almost half the filesize. Let me at it! Copy the `dest` URL:
$ curl http:\/\/smushit.zenfs.com\/results\/5a737623\/
smush\/%2Ffiles%2Fsprt%2Fresult%2Fresult-sprite.png > result/smushed-sprite.png
And that's that.
Recap
- create image:
$ convert *png *gif -append PNG8:result/result-sprite.png
- get dimensions:
$ identify -format "%g - %f\n" *png *gif
- optimize:
$ curl http://www.smushit.com/ysmush.it/ws.php?img=http://url...
Test page to play with the result-sprite is here.
For some more ideas and a different imagemagick command for generating sprites - see the very original post announcing the csssprites.com.
- 1.png
- 2.gif
- dot.png
- phoney.gif
- tw.gif