CSS Sprites with Inline Images

Avatar of Chris Coyier
Chris Coyier on

CSS Sprites is a technique where you use a background-image, a set width and height, and adjust the background-position to display only the portion you need to show. This way you can use a single image and display lots of different graphics with it, saving server requests and speeding up page load times.

The “sprite” is the single, combined graphic. We can use this same theory, only instead of using background-image to show the graphic, we can use an image right in the HTML itself (inline image).

 

View Demo

 

Why?

I don’t know if I have a perfect answer. This is mostly just a proof of concept and demo of how to use the CSS clip property. Although, inline images are just inherently different than divs with backgrounds. The image is “content” while an empty div is not.

CSS Clip

The theory is to use the clip property of CSS to trim the image down to display only the section of it needed to show. Preparing the image would be the same as creating any other CSS sprite:

You display it with regular HTML, giving it a couple of class names we’ll use:

<img src="images/arrow-sprite.png" alt="arrow" class="clip pos-1" />

In order to use CSS clip, the element must be absolute positioned, so we’ll do that with the generic “clip” class, and apply some default/required top and left values. Then we’ll set up a class name for each of the different images within the sprite. One position class name for each image:

.clip               { position: absolute; top: 0; left: 0; }
		
.pos-1              { clip:rect(0 48px 48px 0); }
.pos-2              { clip:rect(0 96px 48px 48px); left: -48px; }
.pos-3              { clip:rect(48px 48px 96px 0); top: -48px; }
.pos-4              { clip:rect(48px 96px 96px 48px); top: -48px; 
                      left: -48px; }

Notice the negative top and left values applied for the different positions. This is necessary to move the image back up to the standard position you would expect it to appear. However much of the image you chop away from the top and left, you scoot it back up and to the left that far. This is because the image will occupy the same space as the entire sprite, just have parts of it not appear. But thanks to absolute positioning, this extra space won’t affect anything else and we can nudge it back into place without affecting anything else.

Each “position” follows a rectangle pattern in shorthand, just like margin or padding use in shorthand: Top, Right, Bottom, Left. Fair warning… this can feel a bit weird to write. It feels more natural to write Top, Left, Bottom, Right, like X,Y coordinates, but that’s just not how this works.

It is a little limiting that it must use absolute positioning. If you want to keep your image as part of the regular flow of the document the best you can, you can always wrap the image in a div with relative positioning.

<div class="clipwrapper">
   <img src="images/arrow-sprite.png" alt="arrow" class="clip pos-1" />
</div>
.clipwrapper        { position: relative; height: 48px; width: 48px; }

Same Server Use

Browsers are smart enough to know that if the same image is used in more than one place on the page, it still only needs to load it once. Just as efficient as traditional CSS sprites. Look ma, just one resource:

Browser Compatibility

This works in IE 6, 7, and 8, plus all the good browsers I tried. That makes this absolutely usable all around.

NOTE: The CSS spec calls for commas between the values in the clip property, but apparently older IE doesn’t like them and it works fine without them in newer browsers.