A strongly graphical web page will usually feature most of its navigation as icons. There are several ways of creating these icons: creating them with an appropriate Unicode symbols, bitmaps, or SVG. In this article, I'll focus on the second option.

To add interactivity, we have to swap the initial image with a second image, usually on mouse rollover. The simplest way to do that is to place the first image as a background, and on hover, swap it for a second. This technique is known as CSS spriting.

Our first image, multimedia.png, looks like this:

This is our second image, multimedia-hover.png, with a glow effect.

This is our basic HTML:

<nav>
	<a href="#" id="multimedia"></a>
	<a href="#" id="storage"></a>
</ul>

To this, we add this CSS:

nav a {
	display: inline-block;
	width: 171px;
	height: 123px;
}
a#multimedia {
	background-image: url(multimedia.png);
}
a#multimedia:hover {
	background-image: url(multimedia-hover.png);
}

There are two conditions that must be met for CSS Sprites to work correctly:

  1. Both images must be exactly the same size.  Trying to swap images of different sizes will result in the apparent motion of the icons on mouseover, “jumping as they move between states. This takes careful design.
  2. The a tag must be given a height and width that exactly matches the size of the initial image. This means that the a tag must be set to display: block or inline-block, or be provided with enough padding to see through its window to view the background image.
  3. But wait! We can improve on this: if the window of the a element is only large enough to see one of the image states, why don’t we merge the images together, and show just one half or the other using background-position? By doing so, we load just one image, rather than two, and reduce the number of HTTP requests, which is one of the central techniques to speeding up the load time of a web page. We also eliminate the possibility of seeing a flash as the hover image is loaded for the first time.

    Our HTML is unchanged, but the CSS changes to:

    a#multimedia {
    	display: inline-block;
    	background-image: url(multimedia.png);
    }
    a#multimedia:hover {
    	background-position: bottom left;
    }
    JQuery UI CSS Sprite icon panel

    You can take this much further and create an entire panel of icons in a single image, shifting it around to show different icons for different links using background-position, significantly saving load time.

CSS Sprites are a useful technique, but have some significant drawbacks:

  • If the images don’t load for any reason, your users will likely be lost.  Unlike real images in an <img> tag, background images do not have a text alternative. If they don’t load, nothing shows.
  • Lack of alt text reduces semantics and . Search engines will still follow the link, but they won’t be able to able to understand its context, as there is no text within the link itself.
  • Changes to the design can mean a lot of rework to an icon panel, especially if the icons change in size (although this could be mitigated by using background-size).