Posted 01.03.2011

Posted 01.03.2011

Popping CSS Sprites like Tylenol to Alleviate the Pain

Several weeks ago, I posted a tweet about CSS Sprites. — I thought I’d go into a little more detail than 140 characters.

In layman’s terms, what are CSS Sprites?

Let me give you a metaphor: I have a stack of pictures I want you to look at it. You come to me, I give you 1 picture. You take it, look at it, and then come back to me for the next picture. This is fine. It works. It gets the job done. But, let’s be honest, after the 4th or 5th time, definitely the 23rd time, you’re tired of coming and going.

Enter CSS Sprites.

Instead of giving you one picture each time you came, what if, I just gave you one large sheet that had all the pictures on it. I’m putting the responsibility on you to handle the large sheet and focus on each individual picture as you’re ready for it. A larger sheet, yes, but not as much coming and going.

CSS Sprites = same thing.

The Real World (not MTV)

When you come to my website, instead of giving you 10, 20, 30 little icon images, I’ll give you 1 large image that has all of those icons on it.

You may be surprised to discover, but this is very popular technique that sites like Amazon and Apple and YouTube implement. Check it out:


YouTube Sprites

Apple Sprites

Looks funny, right?

Is this really more efficient?

Check out this article: Performance Research: What the 80/20 Rule Tells us about Reducing HTTP Requests. — OK, I know you probably didn’t read all of it. As the title implies, it uses the 80/20 principel to talk about reducing load time. As Yahoo’s UI Blog, they used as an example. 10% of their time was spent retrieving HTML, the other 90% is spent fetching other components for the page (images, scripts, and stylesheets)!

Granted this post was written in 2006 (CSS Sprites aren’t anything new), but they some ran tests on other popular sites:

  Time Retrieving HTML Time Elsewhere
Yahoo! 10% 90%
Google 25% 75%
MySpace 9% 91%
MSN 5% 95%
ebay 5% 95%
Amazon 38% 62%
YouTube 9% 91%
CNN 15% 85%

So, what does this tell us?

Reducing the number of HTTP requests has the biggest impact on reducing response time and is often the easiest performance improvement to make.

OK, I’m Convinced, now what?

Well, I’ve been implementing sprites as a large background image.

Demonstration? Yes, please.

Here’s a screenshot of the top right corner of my header.

The Care Ring Header Image I created a background image where all my icons that are stacked neatly.

Here’s the HTML:

<div id="login_buttons"> 
    <a href="#" title="LOGOUT" class="logout">LOGOUT</a> 
    <a href="#" title="SETTINGS" class="settings">SETTINGS</a> 
    <a href="#" title="REPORTS" class="reports">REPORTS</a> 
    <a href="#" title="BUGS" class="bugs">PROBLEMS</a> 
    <a href="#" title="HELP" class="help" >HELP</a> 

In case you’re wondering, I do have links plugged into the href parameter. I just removed them for demonstration purposes.

Then, in the CSS, I have 7 different classes. 1 main class that defines all the properties, like padding, float, etc (another main class that defines hover) and 5 different classes that define the positioning for each icon.

#login_buttons a                    {float: right; margin-top: 7px 0 0 30px; background: transparent url('../images/icons_in_header.gif') no-repeat; height: 22px; padding: 3px 0 0 27px;}
#login_buttons a.bugs                {background-position: 0 -100px;}
#login_buttons                {background-position: 0 -50px;} 
#login_buttons a.reports            {background-position: 0 -25px;}
#login_buttons a.settings            {background-position: 0 -75px;}
#login_buttons a.logout                {background-position: 0 0;}
#login_buttons a:hover                {color: #628d12; text-decoration: none;} 

Are you following me so far?

Notice the background-position has a negative value. That’s because we’re essentially sliding the background up. Essentially, what we’ve created looks like this:

The grayed out parts of the background image, you can’t see because we’ve set the height to 22 pixels.

Sweet! This works great…until….

My Dilemma

As I pointed out earlier, you can’t see the grayed out parts of the background image because we’ve set the height to 22 pixels. Well, what happens when you have content that needs to be able to grow vertically? If you change height to min-height, you’re able to see the stacked icons. Not what I want!

That’s when I found a fantastic article by Chris Coyier: CSS Sprites with Inline Images.

Chris (yes, we’re on a first name basis) does a fantastic job of explaining everything in his blog post. But, essentially, instead of using a background image on a container, you use the CSS clip property on an image.

Another demonstration?

I was trying to achieve something like this:

With my CSS background technique, I kept running into this:

See how the tags icon keeps appearing. beat my head against the wall

I had to change my code. Here’s my new HTML:

<div class="clip_wrapper left"> 
    <img src="images/icons_inline_content.gif" class="clip clip_teams" /> 
<div id="team_content"><span id="my_teams_list">
    <a href="#">Congregational Care</a>, 
    <a href="#">20 Somethings</a>, 
    <a href="#">Student Ministry</a>, 
    <a href="#">Kairos</a>, 
    <a href="#">Haywoods</a>, 
</span><span class="small"><a href="#" id="edit_teams">[edit]</a></span>

In the CSS:

.clip_wrapper                        {position: relative; height: 26px; width: 26px; margin-right: 3px; top: -5px;}
.clip                                {position: absolute; top: 0; left: 0;}
.clip_teams                            {clip:rect(0 26px 26px 0);} 

In order to use CSS clip, the element must have an absolute position

It’s a little more code. It might be edging on divitis, but it gets the job done and achieves the look I want.


Interested in knowing more? Here are a few sites that I looked at and found helpful:


  • Peggy

    Home run! Great sulggnig with that answer!