CSS Sprites generation tool

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?

This entry was posted on Wednesday, June 27th, 2007 and is filed under Ajax, CSS, JavaScript, performance, php. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.


Get notification for future posts: follow me on Twitter or subscribe to my RSS feed

19 Responses to “CSS Sprites generation tool”

  1. PHPDeveloper.org Says:

    Stoyan Stefanov’s Blog: CSS Sprites generation tool…

  2. developercast.com » Stoyan Stefanov’s Blog: CSS Sprites generation tool Says:

    [...] 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. All in a days work… Says:

    [...] 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. Daniel Papasian Says:

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

  5. Stoyan Says:

    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. considered harmful Says:

    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. Stoyan Says:

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

  8. php-web-developer Says:

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

  9. e devlet Says:

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

  10. örnekleri dersleri Says:

    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 Says:

    @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: Ottimizzare le immagini di una pagina web | JuliusDesign Says:

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

  13. CSS Sprites: Ottimizzare le immagini di una pagina web Says:

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

  14. Un tool per generare CSS sprites | Edit - Il blog di HTML.it Says:

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

  15. Performance Calendar » Blog Archive » The pain points of having fewer components Says:

    [...] 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. Command-line CSS spriting / Stoyan's phpied.com Says:

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

  17. The pain points of having fewer components / Stoyan's phpied.com Says:

    [...] 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. febri Says:

    awesome…
    cau u share this project ?? tq

  19. Mac Adobe Says:

    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.

Leave a Reply