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!
30 responses to “Better Image Preloading with CSS3”
@Jeff lets me explain a bit.
I am using a jQuery stylesheet changer on my blog which changes the “look” of my website. Now things happened like this, i removed the css because of multiple http requests to the server and download the images again and again, i should only have the CSS load for the main-page homepage only rather than for all the pages.
Both the change-theme menu and the different images for each theme are loaded also when the user enters the website. I looked with firebug in the NET category. Now let’s say the user wishes to change the theme from the default to something else. He clicks on the start menu icon -> change theme -> and when the menu loads he doesnt have the background image already cached and it downloads it again, EVEN THO IT WAS REQUESTED WHEN THE USER FIRST LANDED ON THE PAGE. I dont have to mention the theme images not being loaded at all, but i do have in my firebug calls for those images at the start.
The paths are either relative like “
./images/theme1/img1.png
” and i have tried with absolute likehttp://alexdweb.com/blog/wp-content/themes/inanisMod/images/theme1/img1.png
and both methods have not yeilded results.Hopefully i could make myself rather clear. If you want i can give you a live example.
@Alexandru: perhaps there are some expiration and/or caching rules being applied to the images via HTAccess or elsewhere? It sounds like something may be telling the browser to not cache the images.
Good technique… I use it sometimes as it does not function anywhere…
@Alexandru, Jeff
have come across this issue when loading in font-face files
* IE will download the file immediately when it encounters the css declaration.
* Gecko, Webkit, and Opera all wait until they encounter HTML that matches a CSS rule
full explanation here
http://paulirish.com/2009/fighting-the-font-face-fout/
HTH
-9999px
>-999em
Write less do more :D
@Jennie: thanks for the link – I will savor the details of that post. What do you think is the optimal workaround for this issue?
@Kartlos: Nice :)
I’ve been thinking about this for a while, and once I get some time, I will probably implement this idea.
Personally, I do many things at once, and having one web browser suck all the available connections/bandwidth seems greedy to me, and also creating many image objects seems that it would bloat the memory footprint of a particular page.
The idea I had was to have a script that would accept the list of images to preload, and using one image object, load them sequentially.
Using CSS sprites really negates using preloaders, and I’ve long stopped using them. Sure mobile browsers (I’m looking at you Safari) still have a ways to go to render them properly, but still ;)
@WSz: For design elements, yes, but not so for preloading gallery images, shopping carts, and so on. Very difficult to configure as CSS sprites ;)
@Jeff,
I’ve always used js galleries and let them respectively preload the images, but I’m thinking it wouldn’t be that hard to map out a CSS3 gallery using sprites. I have a concept in my head that can be done using jquery, but maybe it’s possible to do it even without js. Maybe a project for a rainy Sunday?
I’ve never done an e-commerce website so can’t comment on shopping carts ;)
PS: oh, and while I really dig the design of your website, I do have a problem with the “Submit Comment” button: It looks like an input field and not an actual button. As raw usability goes, that’s not a good thing ;)
Why not just use
display:none
?nev – great question.. I’m thinking that using
display:none
causes problems for some browsers.. (but it’s been awhile)