Free! CSS Sprites: Image Slicing's Kiss of Death

3640 Users read it.
by bruce lawson

In this free article Dave Shea shows how to use an innovative new CSS technique which he calls CSS Sprites that works in all modern browsers (except Opera 6), and replaces old-school image slicing and dicing (and the necessary JavaScript) with standard CSS and HTML lists.

This article was originally published by A List Apart and is reproduced by kind permission. It's copyright © 1998–2004 A List Apart Magazine, Happy Cog Studios, and Dave Shea.

 

User Rating (5 votes)
Support

Details...
User Level:Any
Technologies:CSS, XHTML, HTML
Number Of Pages:8

Applying the CSS

With those basic building blocks, it's time to build the CSS. A quick note before we start — because of an IE glitch, we'll be tiling the after image on top of the before image when we need it, instead of replacing one with the other. The result makes no real visual difference if we line them up precisely, but this method avoids what otherwise would be an obvious "flicker" effect that we don't want.

      #skyline {
        width: 400px; height: 200px;
        background: url(test-3.jpg);
        margin: 10px auto; padding: 0;
        position: relative;}
      #skyline li {
        margin: 0; padding: 0; list-style: none;
        position: absolute; top: 0;}
      #skyline li, #skyline a {
        height: 200px; display: block;}

Counter-intuitively, we're not assigning the before image to the links at all, it's applied to the <ul> instead. You'll see why in a moment.

The rest of the CSS in the above example sets things like the dimensions of the #skyline block and the list items, starting positions for the list items, and it turns off the unwanted list bullets.

We'll be leaving the links themselves as empty, transparent blocks (though with specific dimensions) to trigger the link activity, and position them using the containing <li>s. If we were to position the links themselves and effectively ignore the <li>s, we'd start seeing errors in older browsers, so let's avoid this.

Positioning the links

The <li>s are absolutely positioned, so why aren't they at the top of the browser window? A quirky but useful property of positioned elements is that all descendent elements contained within them base their absolute position not off the corners of the browser window, but off the corners of the nearest positioned ancestor element. The upshot of this is that since we applied position: relative; to #skyline, we're able to absolutely position the <li>s from the top left corner of #skyline itself.

      #panel1b {left: 0; width: 95px;}
      #panel2b {left: 96px; width: 75px;}
      #panel3b {left: 172px; width: 110px;}
        #panel4b {left: 283px; width: 117px;}

So #panel1 isn't horizontally positioned at all, #panel2b is positioned 96px to the left of #skyline's left edge, and so on. We assigned the links a display: block; value and the same height as the <li>s in the past listing, so they'll end up filling their containing <li>s, which is exactly what we want.

At this point we have a basic image map with links, but no :hover states:

It's probably easier to see what's happening with borders turned on:

Follow us on twitter Subscribe to our RSS feed
Activate your free membership today | Login | Currency