Nov 12, 2008

How to Preload Images When You Can’t Use CSS Sprites

I have already shown how to use css sprites, but there are times when you just cannot use them. Sometimes you still want the benefit of preloading the image, so you have to get creative.

An Example

CSS Sprite

I have created a demo of a CSS sprite in action. The sprite has the two images sitting on top of each other, and each link is using the image as a background image and then shifting the position of it when hovering.

a.spriteVert { <br /> background: url(http://trevordavis.net/images/content/2008/11/sprite-vert.gif) no-repeat top left;<br /> padding-left: 30px;<br />}<br />a.spriteVert:hover { background-position: bottom left; }

It works great in the first example, but what happens if the user resizes their text? The sprite starts to break. When I am building a site, I am always thinking with the bulletproof mentality of Dan Cederholm, so this is just not an acceptable solution.

Now, we obviously couldn’t position the images next to each other because we would still have a problem when shifting the image around.

The Solution

Typically when you are using CSS sprites, there is another element containing the anchor. Whether it’s a list item, paragraph, div, etc; this solution will work unless you have a background image on that element as well.

Example

Background image for hover stateBackground image for unactive state

I have created a second demo that “fixes” the first example. The idea behind it is that instead of combining the images into 1 image, you split it into 2. Then you place the image that is being shown on hover as the background image on another element (preferably a containing element), just positioned off the screen.

Then when you hover, you switch the background image, which has already been preloaded, so you don’t get that “white flicker”. That may be a little hard to understand, so I’ll give an example.

The Markup

<p class="spriteContainer"><a href="#" class="spriteVert">Hover Over Me</a></p><br /><p class="spriteContainer"><a href="#" class="spriteVert spriteVert2">Hover Over Me</a></p><br /><p class="spriteContainer"><a href="#" class="spriteVert spriteVert3">Hover Over Me</a></p>

Note: The extra classes of spriteVert2 and spriteVert3 are just used to change the font size.

The CSS

p.spriteContainer { <br /> background: url(http://trevordavis.net/images/content/2008/11/sprite-hover.gif) no-repeat -9999px -9999px;<br />}<br />a.spriteVert {<br /> background: url(http://trevordavis.net/images/content/2008/11/sprite-off.gif) no-repeat top left;<br /> padding-left: 30px;<br />}<br />a.spriteVert:hover { <br /> background-image: url(http://trevordavis.net/images/content/2008/11/sprite-hover.gif);<br />}

More Explanation

So looking at the previous example, I am adding the background image that I want to appear on hover as the background image on the paragraph with a class of spriteContainer, and I am positioning it way off the screen.

Then when I hover over an anchor with a class of spriteVert, I change the background image to be the one from the paragraph with a class of spriteContainer.

Conclusion

While this is not as ideal as using CSS sprites because you increase the number of hits to your server, it can help to eliminate the white flicker that you get if the image is not preloaded.

Categories