Latest TweetsGreat post about the latest power grab: www.eff.org/deeplinks/2018/09/…
Perishable Press

Better Image Preloading with CSS3

I recently added to my growing library of image-preloading methods with a few new-&-improved techniques. After posting that recent preloading article, an even better way of preloading images using pure CSS3 hit me:

.preload-images {
	background: url(image-01.png) no-repeat -9999px -9999px;
	background: url(image-01.png) no-repeat -9999px -9999px,
		    url(image-02.png) no-repeat -9999px -9999px,
		    url(image-03.png) no-repeat -9999px -9999px,
		    url(image-04.png) no-repeat -9999px -9999px,
		    url(image-05.png) no-repeat -9999px -9999px;
	}

Using CSS3’s new support for multiple background images, we can use a single, existing element to preload all of the required images. Compare this method with the old way of using CSS to preload images:

.preload-01 { background: url(image-01.png) no-repeat -9999px -9999px; }  
.preload-02 { background: url(image-02.png) no-repeat -9999px -9999px; }  
.preload-03 { background: url(image-03.png) no-repeat -9999px -9999px; }
.preload-04 { background: url(image-04.png) no-repeat -9999px -9999px; }
.preload-05 { background: url(image-05.png) no-repeat -9999px -9999px; }

As you can see, the CSS3 method is a much cleaner way to preload your images using a single CSS selector. Note that we’re also going to need to ensure the background images aren’t being displayed in the preload element. For that, I suppose we could either hide the element using display:none or else position the images far off screen using -9999px positioning.

Pros

This technique works great in supportive browsers now, and the support will only get better moving into the future. Notice that we can include a partial fallback mechanism by preloading one of the images as a single background property value. Browsers that don’t get the multiple stuff will fallback to the single-value background property instead.

Also, browser support for CSS is much better than for JavaScript, so big improvement there. Beyond these things, the sheer ease of picking an element and adding all of our preload images as backgrounds is simply too easy not to take advantage.

Cons

Well, let’s see.. current browser support is not as good as it could be, mostly because of Internet Explorer. So besides the fact that IE may never understand multiple background-images, the downsides to using this method are pretty much nil as far as I can tell. Perhaps I am missing something completely obvious..? Maybe someone will elaborate on the non-presentational use of CSS? ;) Chime in!

Jeff Starr
About the Author Jeff Starr = Web Developer. Book Author. Secretly Important.
Archives
30 responses
  1. This is clever. Non-semantic markup makes me cringe, but I prefer it to unnecessary JavaScript. How does this method affect the perceived loading time of the visible images on the page?

  2. Jeff Starr

    Not sure, but I think that CSS images are loaded according to their position within the stylesheet. So by placing the preloading selector at the bottom of the CSS file, all other images should load first.

  3. I like it, very clean. The only thing still making me nervous is all of those http calls- I’d be tempted to merge them into a single sprite, especially if they’re ‘layout’ graphics, and not editorial. Happy New Year!

    Trav

  4. Jeff Starr

    Yes, good point. I think that merging your background images into as few sprites as possible is a good idea, but they already will be loaded from their actual display selectors, so no need to preload them. I think this technique is best for editorial/gallery images, but keeping in mind the overall number of HTTP requests is definitely wise.

  5. I had some preloading CSS3 thoughts as well… using pseudo selectors like :after to attach background images. That way you could actually use the same selector you are probably preloading the image for, so the stylesheet would be cleaner. Alas, in my testing, it didn’t want to preload images using :after… but my testing wasn’t very extensive.

  6. Steffan Williams January 4, 2010 @ 11:01 am

    Very nice indeed.

    @Kristi, it doesn’t have to be non-semantic though, right? All you have to do is apply the proposed class to any element on your page that you don’t want a background image on.

    It’s a nice way, moving forward, as more browsers support CSS3. Not sure if I’d opt for it myself, currently, but its still nice.

  7. Pretty interesting idea. I may give it a whirl on a smaller project just to see how it works in practice, and not just as a theory. But, again, very interesting idea. Thanks!

  8. Jeff Starr

    @Rod: you know it will – it’s all just a theory even when it works :)

  9. Good example but the browser support isn’t that great with mutiple backgrounds at the moment. I did a post on preloading images using the CSS2 content property which allows me to preload multiple images in the 1 line of CSS https://www.thecssninja.com/css/even-better-image-preloading-with-css2.

  10. Jeff Starr

    @Chris: good idea using the :after pseudo-selector to provide more flexibility. I will do some experimenting and see if there is a good cross-browser way of using it for preloading.

    @Ryan: that looks like a great way of doing it with CSS2.1 – thanks for sharing :)

  11. Alexandru Dinulescu January 6, 2010 @ 5:04 pm

    Does this technique works for background images?
    For ex:
    I have in my css a large background-image: url("./img.png"); that is accessed when i switch the class of an item via javascript. If i dont have the website cached, instead of loading that image at the beginning and then taking it from the cache and applying on the element it just loads it again.
    So this thing does not work for background images.

    It may only work for images that are in the tag.

    If i am wrong please correct myself, because from what i tested on my website i couldnt figure a way to do this.

  12. Jeff Starr

    @Alexandru: are you sure the same image is being called using the (exact) same path? also, you say, “if I don’t have the website cached..” – does that mean that the results are different in the other case (when the browser is primed)?

[ Comments are closed for this post ]