CSS Sprites

What is a Sprite Sheet?

Put simply, a sprite sheet is an image file composed of smaller individual graphics. These graphics can be various states of a UI element, individual frames of an animation, or even various design elements that appear commonly throughout a site’s design. This practice is definitely not new – it’s been done since the early days of video games, however since being introduced to the world of web design they’ve generally been considered as good practice. There’s a lot of debate about whether or not using sprites are actually beneficial, but as with most techniques there is always a time and a place to use them. Before we get into the pros & cons let’s first review how to implement a sprite.

Adding Sprites To Your Site

Sprites are fairly straight forward to implement, it just takes a little time creating your sprite sheet and defining the CSS rules that will best suit your needs. They can be applied to various HTML elements such as lists (both ordered & unordered), divs, spans, anchor tags, and so on. As I mentioned above one way they can be used are for hover states, which is the example we’ll be exploring. Here we have a version of the sprite map used on this site which includes two states – default and hover.

social media sprite from battlehillmedia.com

Various elements of a sprite sheet

Organization is very important when creating a sprite sheet. If you use a systematic grid approach to laying out your elements it will make calculating your background-position values a bit easier later on, especially if all your elements are the same exact size as with the example above.

CSS
.sprite {
    background-image:url('social.png');
    background-repeat: no-repeat;
    display:block;
    width:64px;
    height:64px;
}

.facebook { background-position: 0px 0px; }
.facebook:hover, .facebook:active { background-position: -64px 0px; }

.twitter { background-position: 0px -64px; }
.twitter:hover, .twitter:active { background-position: -64px -64px; }

.instagram { background-position: 0px -128px; }
.instagram:hover, .instagram:active { background-position: -64px -128px; }

Here’s our CSS which defines essentially two types of classes used. The .sprite class is a generic class that is applied to every sprite element and is where we define the sprite image as the background-image. If all your graphics are the exact sane size then you should set the width & height rules here as well to reduce redundant code. Then we have graphic specific classes – .facebook, .twitter, .instagram. These all have a background-position rule set that defines where in the sprite sheet the background should begin. If your sheet contains various sized graphics then this is where you’d define their dimensions. Each element will have at least two rules for the default & hover states.

I’ve included the :active pseudo-class to my :hover classes due to the fact that if we’re using a mobile device there technically is no way to “hover” on an element, so once the element is touched it will use the same rules and still appear selected.

HTML
<h3>Inline-Block List</h3>
<ul>
    <li class="sprite facebook"></li>
    <li class="sprite twitter"></li>
    <li class="sprite instagram"></li>
</ul>

<h3>Anchors within Inline-Block List</h3>
<ul>
    <li><a class="sprite facebook" href="#"></a></li>
    <li><a class="sprite twitter" href="#"></a></li>
    <li><a class="sprite instagram" href="#"></a></li>
</ul>

<h3>Div</h3>
<div class="sprite facebook"></div>

<h3>Span</h3>
<span class="sprite twitter"></span>

<h3>Anchor</h3>
<a class="sprite instagram" href="#"></a>

And that’s pretty much all there is to it. You can go one step further to target high DPI displays by creating a high res sprite sheet and scaling your images after the fact with CSS which will give you nice, clean graphics instead of something that resembles a bunch of fuzzy legos. To achieve this we’ll need to make a small CSS change along with creating a high res sprite sheet.

We start by adding background-size: 200% auto; to our sprite class. This tells the background to scale according to it’s parent element. You might be wondering, “Why 200% instead of 50%?” Well, when we defined our sprite class we gave it dimensions of 32x32px. The background-image rule uses these values to define what it considers 100%, so by using 200% we’re only displaying half of the background image which is just one single image on the sprite sheet. I settled on 200% as a good medium between quality and file size, however if you decide you’d like to target an specific DPI you’ll have to divide that number by 72 (DPI of your common monitors) and then multiply your intended dimensions for your sprite sheet by your result. For example, if I want graphics that will look great on a 360dpi display and my original sprite sheet is 64x96px, I would size my sprite sheet at 256x384px (360/72 = 4, then 64×4 & 96×4, respectively). A little extra work, but definitely worth the effort.

Demo Source

Pros Vs. Cons

As I mentioned earlier, there is a lot of debate over whether or not CSS sprites are actually beneficial or more trouble than they’re worth. Here are the pros vs. cons on using sprite sheets –

Pros

  • Reduce the number of HTTP requests being made
  • Mouseovers won’t ‘flicker’ when displaying for the first time
  • Potentially smaller file size

Cons

  • Creates a bottleneck, have to finish downloading image before continuing to render document
  • Increased maintenance
  • Not ideal for accessibility

Final Words & Closing Thoughts

Ultimately the choice is up to you, the developer. I personally don’t believe the most common disadvantages of using sprites are a big enough concern to stop using them. Theoretically, downloading a sprite sheet should take less time than downloading all the graphics individually. As for maintenance goes they are relatively easy to maintain if you’re competent with photoshop. I would not recommend using sprite generating tools until you are comfortable enough implementing them manually, once you’re comfortable enough creating them manually you can take shortcuts. And lastly as far as accessibility goes, I’m not suggesting to replace all your images with sprite sheets. In fact I’m suggesting the opposite – only use them when you absolutely have to. Any image that is purely for design should be in your CSS anyways, the W3C only recommends using <img> tags when you’re adding meaningful content to a site, e.g. a product image. There is an alternative if you absolutely want to have a fallback and include alt text, however this approach won’t work if you’re using transparent PNGs. At the end of the day it’s the nature of your project that will determine if you should use them or not. What I suggest is take the time to learn the technique and after you’ve mastered that you can determine if it makes sense to add to your project.