How to make CSS Sprites

September 26, 2008
CSS sprites is a very cool concept for optimizing the load time for websites. The basic theory is that an HTTP connection is costy and by combining several logical images into one physical image file you can reduce the number of HTTP connections and thereby increase the responsiveness of your websites.

Me and Kariem use a lot of CSS sprites for our skins in Ra-Ajax. The latest Window skin is one example and can be seen at our newly updated Ajax Window sample which actually was released only hours ago. The whole foundation of CSS sprites is the capability to add up in CSS background images for your HTML elements in addition to setting the x & y offset of where to start reading the image. Combine that with a width and height of some sort on your HTML elements, add some CSS background repetition to the mix, and VOILA! You've got a perfect recipe for adding a huge slew of logical images into one physical file and thereby reduce the number of HTTP connections DRASTICALLY!

CSS sprites to optimize your website
(Images are blown up in size to make concept easier to understand)

The above image is the sprite.png image from our Ajax Window sample. And as you can see we have several logical images glued into one physical image file here. That specific file actually have 6 logical images; all the corners of our Ajax Window skin in addition to the close button in normal and hovered state.


CSS sprites dissected


If you look at the CSS for the Window you will see something looking roughly like this;

.alphacube_nw
{
background: transparent url(skins/window/alphacube/sprite.png) no-repeat 0px 0px;
/*...[snipped intentioanlly]...*/
}
.alphacube_ne
{
background: transparent url(skins/window/alphacube/sprite.png) no-repeat right 0;
/*...*/
}
.alphacube_n
{
background: transparent url(skins/window/alphacube/h-sprite.png) repeat-x 0 0;
/*...*/
}
.alphacube_close
{
background:transparent url(skins/window/alphacube/sprite.png) no-repeat -10px 0;
/*...*/
}


The whole idea is that the background CSS property takes several interesting parameters in addition to the url to the image file and the background-color. And the ones which are of particular interest for us are the repeat, top & left properties. By manipulating those three properties you can easily use the same physical image for a whole bunch of logical images. The order of the parameters are roughly like this;
  • background-color (will display while image loads)
  • image url
  • repetition (no-repeat, repeat-x or repeat-y)
  • scroll or fixed (optional, not in the sample above)
  • left (note NEGATIVE OFFSET)
  • top (note NEGATIVE OFFSET)


If you take a look at the alphacube_close class you will see that we set the left property to -10px. Note that this means that the image should be moved 10 pixels to the left. And NOT that it starts at -10px according to the top/left corner. What can I say, I didn't contribute to the CSS standardization process, I know it's counter-intutive, but that's the way it is...

I'll repeat the most important parts to understand one more time;
the top and left property are NEGATIVE offsets which means that 10 logical pixels to the right into the image surface will have to be typed as -10px in your CSS file.

If you count the pixels to the close button in the CSS sprite above you will see that the button starts at [10,0] coords from the top left corner. So by "moving the image 10 pixels to the left OUT of the physical image file" we get the right coordinates for our CSS close button. Then by adding some sort of width by using width, padding-left or something similar on the HTML element we can "stop" the image rendering where it is supposed to stop the rendering. Without an explicit width of some sort the "next" logical image in your sprite will show up and distort your background-image of your HTML element...

If you take a look at the alphacube_n class however you will see that it has a repeat-x value for the repetition. This basically says that the image is supposed to be "repeated until end of HTML element". You can also repeat images with repeat-y. This feature makes it possible for you to have "really long images" which are physically only one pixel wide. (or high)

Take a look here at the h-sprite.png which is used in the alphacube_n class;

horizontally repeated CSS sprites

The same is obviously also possible for repetitions going vertically instead of horizontally by using the repeat-y instead of the repeat-x value. Though then you'd obviously had to have a very *LONG* image instead of a very "high" image... ;)


Limitations of CSS sprites



There are a couple of limitations for CSS sprites, most of them comes from the fact that you CANNOT combine images which are vertically repeated together with images that's horizontally repeated. If you think about this for 7.5 minutes you'll understand why. This means that you'll mostly never be able to add all logical images into one physical image file. But the "speed of light solution" should probably never contain more than 3 images. Though sometimes you would want to have more since the difference in width/height is just "too big". If you have a website with 50 images and you manage to reduce those numbers to 3-10 physical files (and thereby the number of HTTP connections equivalent) your users will experience a far more responsive and fast loading website by using CSS sprites. And you'll have a far better YSlow score to brag about ;)

Another limitation is that logically people would expect this to also work with the <img ... HTML element, which paradoxically is NOT true unless you hack it by having an "empty image" as the src attribute for your images. So paradoxically this will help you with all HTML elements except the only one which really counts in regards to screen readers and accessibility... :(

But all in all it's a great feature of CSS once you get the grip on it, and it will give you a lot of credit in the next meeting in the geek club, which ultimately is what we're all striving for, or ... ? ;)

Have fun, I did :)

Thomas

<< Previous - Ra-Ajax 0.5 out - Comet Support and more...
How to link to a website - and how others should link to you - Next >>

Copyright

All content at this blog is the Copyright of Ra Software AS but can freely be distributed under the terms of GNU Free Documentation License.

Copyright 2008 - Ra Software AS - Sitemap