CSS Sprites generation tool

June 27th, 2007. Tagged: Ajax, CSS, JavaScript, performance, php

Here's my last weekend's project - a web-based tool to generate images for CSS sprites: http://www.csssprites.com. Cool domain name, eh? I couldn't believe it was not taken.

CSS Spr...what?

This is a simple technique used for page load performance purposes. Since HTTP requests are the most expensive thing you can do in regards to front-end performance, you strive for making as little requests as possible. So instead of having the browser download 4 rounded corner images for example, you create one image that has all four. Then you use CSS' background-position to only show the part of the image you want. More on the subject in this ALA article

How does the tool work

You upload as many images as you want and the tool generates a mosaic of all images, gives you the result as PNG and gives you the coordinates you need to use in the background-position declaration. The tool also gives you an html page as an example, so you can save both the PNG and the html page for reference.

Image size

If you properly optimize the big image, you might actually have smaller size than all the individual images combined. In my tool, the PNG image generated is not optimized at all, I leave this to you to use PNGOUT or any other tool you know. Also you can convert the PNG into GIF if that's better for your purposes.

Implementation - PHP

The PHP code is fairly simple. The actual spriting (is that a word?) class takes a list of images and calls getimagesize() on each one to get the dimensions. The image with the biggest height is used as distance between images. The rest is just composing the imagemagick command that will to the work. Here's the important method:

<?php
function combine() {
    if ($this->distance === false) {
        $distance = $this->_biggest;
    } else {
        $distance = (int)$this->distance;
    }
 
    if ($this->output_dir === false) {
        $output_dir = $this->_dir;
    } else {
        $output_dir = $this->output_dir;
    }
 
    $half = ceil($distance / 2);
 
    $coord = array();
    $y = 0;
 
    foreach ($this->images as $i=>$data) {
        $this->images[$i]['x'] = $half;
        $this->images[$i]['y'] = $half + $y;
        $coord[] = '-page +0+' . $y . ' ' . $i;
        $y += $data[1] + $distance;
    }
 
    $cmd = 'convert ' . implode(' ', $coord)
         . ' -background none -mosaic -bordercolor none -border '
         . $half . 'x' . $half
         . ' ' . $output_dir . '/result.' . $this->output_format;
    system($cmd, $ret);
 
    return $ret === 0;
 
}
?>

Implementation - JS

In the spirit of web2 I couldn't afford a complete page reload :lol: although it would've been much simpler. I just had to get fancy. YUI to the rescue. On page load I set up the form for async request, using YAHOO.util.Connection. In case of file uploads YUI generates an iframe behind the scenes and uploads to the iframe. Then it takes whatever is in the body on the iframe and gives it to you instead of the XMLHttpRequest's responseText property.

So the files are uploaded to upload.php which calls the class that has the method mentioned above then loops through the $images property of the said class and writes the example html file as well as prints out a JSON string with the same image information.

YUI's Connection calls my callback function and I get the invaluable responseText. Parsing the JSON with the json.js, I get a JS object. Looping through it and DOM-generating a table of results is the semi-last step. The last is (we're fancy, remember?) to yellow-fade the background color of the result, using YAHOO.util.Animation.

BTW, I got fancy once again and combined and minified json.js with my JS file, so that there is one less request and a side effect impossible to read. The unminified version of the JS that does all the work is here for reference.

Comments

I hope this tool cane be useful for quickly generating those sprites, if only for prototyping purposes. Any comments, requests, bug reports are all very welcome.

And how do you like the version of the tool? Anyone n00b can do "beta", it takes a true h@x0r (or something) to do a better job :D

Ah, yeah, and the page badly needs a stylesheet, do you want to help?

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

20 Responses

  1. Stoyan Stefanov’s Blog: CSS Sprites generation tool…

  2. [...] In his latest post, Stoyan Stefanov introduces a new project he’s working on, the implementation of CSS sprites: This is a simple technique used for page load performance purposes. Since HTTP requests are the most expensive thing you can do in regards to front-end performance, you strive for making as little requests as possible. So instead of having the browser download 4 rounded corner images for example, you create one image that has all four. Then you use CSS’ background-position to only show the part of the image you want. [...]

  3. [...] CSS Sprites generation tool You upload as many images as you want and the tool generates a mosaic of all images, gives you the result as PNG and gives you the coordinates you need to use in the background-position declaration. [...]

  4. Very nice, very useful! Are there plans on releasing the source of the entire project?

  5. Thanks Daniel. I should probably release the whole source code, but I figured the client side js is there already and the only clever part of the server-side is the imagemagick part which I posted. Nevertheless, I should post the whole thing. Maybe after the next update.

  6. And again a CSS sprites generation tool: http://printf.ru/spritr/
    This one comes with CSS, not that it helps, but anyways.
    Not sure about IE (never tested nor willing to do so).
    Emits CSS, too. Optimal rectangle packing coming soon ;)

  7. @harmful – Nice job! Looks very slick too. I love what you’ve done hiding the actual input fields

  8. very usefull and this is a simple technique used for page load performance purposes.

  9. css background examples , Properties , Attribute – - http://css-lessons.ucoz.com/background-css-examples.htm

  10. HI i need your help i really want to create my own website/web page but i dont know how to go about doing it so can you please help me out

  11. Adrian Russell-Falla

    @considered harmful

    wow – that’s the best generator I’ve seen so far – you rock!

    most optimal sprite size, which matters most to me; and also the prettiest UI…

    (am not so keen on not seeing the file names I’ve selected — got confused about where I was in my list of images, and had to start over)

    cheers,

    Adrian Russell-Falla

  12. [...] CSS Sprites generation tool [...]

  13. [...] CSS Sprites generation tool [...]

  14. [...] L’autore, nel presentare il generatore, offre anche il codice PHP e Javascript utilizzato. È tutto in questo post. [...]

  15. [...] is a fun weekend project I did two and a half years ago. Back then I was even more convinced that this technique is wildly underused, still [...]

  16. [...] some more ideas and a different imagemagick command for generating sprites – see the very original post announcing the [...]

  17. [...] is a fun weekend project I did two and a half years ago. Back then I was even more convinced that this technique is wildly underused, still [...]

  18. awesome…
    cau u share this project ?? tq

  19. Pretty portion of content. I just stumbled upon your web site and in accession capital to say that I get in fact loved account your weblog posts. Anyway I will be subscribing in your feeds or even I success you get entry to consistently quickly.

  20. Having read this I thought it was very enlightening.
    I appreciate you spending some time and effort to put this
    short article together. I once again find myself spending
    a lot of time both reading and leaving comments.

    But so what, it was still worth it!

Leave a Reply