CSS Sprites

October 18, 2008

I decided to take the plunge and begin making my site more YSlow compliant. I had already enabled GZip through a custom GZip filter and browser caching for static resources. My next task was to limit the number of resources being served. My first part here was first minifying and combining all javascript and CSS resources. This reduced the number of requests to two for these types of resources. Next was background images. The best way to do this is by using sprites. A sprite is an image that includes one or more other images. CSS is then used to provide offsets into the sprite where the image is actually defined. As a result, you only need a couple of images rather than many. Within my site, this makes a drastic improvement with all the unique background images I use.

I decided to look for an automated tool to convert my CSS and background images automatically. In my findings I came across the utility SmartSprites. This utility uses CSS comments to annotate the CSS file with information about how to create the sprites. Once completed, it processes the CSS file and all images and creates an updated CSS file and sprite images. The CSS updates include the proper background-position attributes that declare the associated offsets. All in all, it was a very useful tool that I highly recommend. It got my images from 15+ to 3 without the hassle of manually creating the sprites.

In using the tool however, I had a couple of issues (which is more of my ignorance for not reading the documentation :) Anyways, here are some helpful tips and advice.

First, the tool uses Ant to launch the process. However, not enough memory wasallocated to the JVM which caused OutOfMemory errors for me. Note that not everyone will need to handle this step. Unfortunately I took several images on my site into one large sprite, so I needed the extra memory. To resolve the memory issues, I merely provided Ant more memory (-Xmx1g) to ensure I had plenty. I did this by creating an antrc_pre.bat file in my home directory with the line:

SET ANT_OPTS=-Xmx1g

Once I had enough memory, I was now ready to start annotating. The first thing I did was define the sprite references at the top of the CSS file. The sprite references allow you to use multiple sprites in the same file. Note that the examples below appear to wrap the lines. Unfortunately that is an issue with the blog software. All examples below should be on a single line in the CSS without wrapping.


/** sprite: sprite; sprite-image: url('../images/sprite.png'); sprite-layout: vertical */

The sprite-layout defines which way to layout images within the sprite. For standard images, this is not important. However, for images with background-repeat, it is very important as CSS and browsers use the image to repetitively show the image over and over. If using the wrong layout, you will get very unexpected results. The best thing to do here is to use three sprites: one for non-repeating images, one for repeat-y based images, and a third for repeat-x images. For example:


/** sprite: sprite; sprite-image: url('../images/sprite.png'); sprite-layout: vertical */
/** sprite: repeatx; sprite-image: url('../images/sprite-horizontal.png'); sprite-layout: vertical */
/** sprite: repeaty; sprite-image: url('../images/sprite-vertical.png'); sprite-layout: horizontal */

Again, make sure those examples are on three separate lines without wrapping. Now that we have our sprites defined, we can being applying to CSS classes. The proper way to do this is to apply a comment after the associated background-image line. You will use the proper sprite reference depending on the type of background repetition.

If using a non-repeating image, use the following example:


.css-class
{
background-image: url('../images/image.jpg'); /** sprite-ref: sprite; */
background-repeat: no-repeat;
}

This example uses a relative path (highly suggested if not required) to obtain the image. In my setup I used a directory structure such as:

build
+ styles
- style.css
+ images
- image.gif

If using repeating images, use one of the following examples:


.repeat-x
{
background-image: url('../images/image.jpg'); /** sprite-ref: sprite; sprite-alignment: repeat; */
background-repeat: repeat-x;
}
.css-class
{

background-image: url(‘../images/image.jpg’); /** sprite-ref: sprite; sprite-alignment: repeat; */
background-repeat: repeat-y;
}

Again, verify that the comments are on the same line as the background image without wrapping. With each image properly annotated, we can now build our updated stylesheet and sprites. To do so, just execute the ant process command (make sure to update the build.properties file first). If everything goes according to plan, you should now have new sprite images and stylesheets that you can use in your layouts.

Here are some things to consider before annotating images. If the image is only used on one or a few pages (such as titles, headers, etc), consider not annotating these images unless very small. If the images are large in size, you will end up with a very large sprite which will reduce performance. In such a case you are better off just having those few pages use another image that will be cached.

Comments are closed.