Command-line CSS spriting

February 19th, 2011. Tagged: CSS, images,

(In Russian)

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:


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 (you're welcome!) or (psst - how bout a glimpse of the past)

Or how about.... on the command line:

$ curl

Result is JSON:


Oh looky, almost half the filesize. Let me at it! Copy the `dest` URL:

$ curl http:\/\/\/results\/5a737623\/
       smush\/%2Ffiles%2Fsprt%2Fresult%2Fresult-sprite.png > result/smushed-sprite.png

And that's that.


  1. create image:
    $ convert *png *gif -append PNG8:result/result-sprite.png
  2. get dimensions:
    $ identify -format "%g - %f\n" *png *gif
  3. optimize:
    $ curl

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

Tell your friends about this post: Facebook, Twitter, Google+

Sorry, comments disabled and hidden due to excessive spam.

Meanwhile, hit me up on twitter @stoyanstefanov