A Little Background…

Of all the tools in my Web Developer’s Toolkit™, perhaps the most used, and the most useful, is a trick called the CSS Sprite. It’s an “advanced” technique that is actually deceptively simple, and leads to fantastic advantages in loading times of web pages.

First, a quick primer. A “sprite” doesn’t refer to a carbonated soft-drink, or a mythical fairy. It’s an archaic computer term that simply refers to a graphic, stored in memory, that can be drawn on the screen. Old video games would define regions of memory (later called a “sprite sheet”) that contain the individual frames of an animation, and by cycling through these regions, the objects on screen would appear to animate.

Sprite Sheets in video games

A sprite sheet (left) and the resulting animation (right). Super Mario is registered trademark of Nintendo Co., Ltd.

The relationship between video games becomes clearer when you think about these sprite sheets. Instead of producing an animation, we can use the technique to reduce code complexity, decrease loading times, improve accessibility, optimize the site for search engines, and provide a “rollover” effect (making the image appear to change when the user moves the mouse over it).

Getting Started

The first step is identifying the images. In the screenshot below, I’ve highlighted the items that I would replace with sprites on a previous iteration of our web site. It’s important to note that these are layout elements. They are not a part of the content of the page, and will not change as frequently.

CSS Sprites - Chili Code

Click to embiggen

In this image, the logo in the top left, styled text in the middle, and button will have better accessibility and search engine friendliness. The icons in the top right and center of the page will have improved loading times, and the large chili will benefit from easier positioning and smoother rendering.

You’ll notice I didn’t highlight the portfolio thumbnails in the bottom right. This is because these images are dynamically inserted by a script, and therefore likely to change. Making them sprites would make them harder to manage in the future.

The Markup

Now that we’ve identified our images, it’s time to write the structure of the page in (X)HTML. Essentially, you can treat every element as if it were a piece of text, as the text will be replaced with images when the page is displayed.

Here is the markup for the very top bar, where the logo and social networking icons are displayed.

<h1><a id="logo" href="#">Chili Code Solutions</a></h1>
<ul id="social-networks">
	<li><a id="facebook" title="Join us on Facebook" href="#">
 Join us on Facebook
 </a></li>
	<li><a id="twitter" title="Follow us on Twitter" href="#">
 Follow us on Twitter
 </a></li>
	<li><a id="linkedin" title="Connect on LinkedIn" href="#">
 Connect with us on LinkedIn
 </a></li>
</ul>

On a text-only browser, assistive screen reader, or search engine robot, these elements will be displayed as text. Accessible and search engine optimized in one fell swoop!

The Stylesheet

To replace the text with an image, we need to use a little CSS magic. This code is proven to work in all but the most obscure browsers.

/* For the logo */
#logo {
	display: block;
	text-indent: -9999px; /* Move the text left 9999px */
	overflow: hidden; /* Hide elements outside the block */
	width: 240px; /* Width of image */
	height: 40px; /* Height of image */
	/* Image */
	background-image: url('images/logo.png');
	background-repeat: no-repeat;
}

This demonstrates the basic principle of replacing text with an image, but it is not a true CSS sprite. Unlike a CSS sprite, the web browser will still make an HTTP request to load the image if it isn’t cached, and there will be no performance benefit.

Real Sprites

The social networking icons are a better example of true CSS sprites. We can use the technique to reduce load times, as well as create a mouse-over effect.

The sprite image is a combination of all the images, arranged into one, similar to the following:

A real CSS sprite

The top row is normal, the bottom is for the mouse-over state.

The idea is we’ll use the background-position CSS property, to position the background inside the visible area.

A visual explanation

Left: Normal style. Right: mouse-over style.

/* For the facebook icon */
#facebook {
	display: block;
	text-indent: -9999px; /* Move the text left 9999px */
	overflow: hidden; /* Hide elements outside the block */
	width: 34px; /* Width of image */
	height: 34px; /* Height of image */
	/* Image */
	background: url('images/social-networks.png');
	background-repeat: no-repeat;
	background-position: 0px 0px; /* Position Image */
}
#facebook:hover {
	background-position: 0px -34px; /* Position Image */
}

Now, when the image is hovered, the background position will change, and the “over” state will be displayed.
By combining the Facebook, Twitter, and LinkedIn into one image, you can reduce the number of HTTP requests, and simply position the background image.

/* Combine into one definition */
#social-networks a {
	display: block;
	text-indent: -9999px; /* Move the text left 9999px */
	overflow: hidden; /* Hide elements outside the block */
	width: 34px; /* Width of image */
	height: 34px; /* Height of image */
	/* Image */
	background: url('images/social-networks.png');
	background-repeat: no-repeat;
}
/* Facebook */
#facebook {
	background-position: 0px 0px; /* Position Image */
}
#facebook:hover {
	background-position: 0px -34px; /* Position Image */
}
/* Twitter */
#twitter {
	background-position: -34px 0px; /* Position Image */
}
#twitter:hover {
	background-position: -34px -34px; /* Position Image */
}
/* LinkedIn */
#linkedin {
	background-position: -68px 0px; /* Position Image */
}
#linkedin:hover {
	background-position: -68px -34px; /* Position Image */
}

The end result? Instead of loading 6 separate images, it loads one. Using background-position to display the area of the image, depending on the id of the element. It’s re-usable code, and it’s accessible, efficient, search-engine friendly.

Leave a Comment

Your email address will not be published. Required fields are marked *

Allowed HTML: a abbr acronym b blockquote cite code del em i q strike strong