Welcome to the new design! Please report any bugs or issues, thanks :)
Web Dev + WordPress + Security

CSS Throwdown: Preload Images without JavaScript

[ Preload Images with CSS ] Clean, easy, effective. You don’t need no stinking JavaScript to preload your images. Nope. Try some tasty CSS and (X)HTML instead! Here’s how to do it with only two easy steps..

Step 1 — Place this in your CSS file:

div#preloaded-images {
   position: absolute;
   overflow: hidden;
   left: -9999px; 
   top: -9999px;
   height: 1px;
   width: 1px;
}

Step 2 — Place this at the bottom of your (X)HTML document:

<div id="preloaded-images">
   <img src="https://perishablepress.com/image-01.png" width="1" height="1" alt="" />
   <img src="https://perishablepress.com/image-02.png" width="1" height="1" alt="" />
   <img src="https://perishablepress.com/image-03.png" width="1" height="1" alt="" />
</div>

..and that’s a wrap! All images are preloaded and ready for calling as you please. Completely valid, standards-compliant image preloading via CSS and (X)HTML!!

Jeff Starr
About the Author
Jeff Starr = Fullstack Developer. Book Author. Teacher. Human Being.
Blackhole Pro: Trap bad bots in a virtual black hole.

68 responses to “CSS Throwdown: Preload Images without JavaScript”

  1. Jeff Starr
    Perishable 2008/02/17 9:21 am

    Hi Nanda, thanks for continuing the conversation ;) Reading your comment, I am assuming that WordPress ate the “<div>” placed directly before the “s” in your first sentence. If so, I would argue that an empty <div> (or any other element) qualifies as “non-semantic” markup, which should also be avoided within a strictly web-standards context. Admittedly, an empty element is an improvement over one that is filled with images, however, I think that your second, CSS-only method serves as a far better solution overall. Do you know if there are any browsers for which the CSS-only technique does not work?

  2. The CSS only method is certainly better, it will work in any browser that supports background images, so far I’ve had no problems in any modern browsers (including IE 6).

  3. Jeff Starr
    Perishable 2008/02/17 3:26 pm

    Excellent — thanks for sharing this method with us. I am going to experiment a bit and perhaps check a few crusty browsers for support. After spending some quality time with the technique, I will update this article and post an “new and improved” version! Thanks again for your help! :)

  4. Hello Perishable.
    Interesting method, but won’t it work if you just use display:none;?

  5. Jeff Starr
    Perishable 2008/05/04 7:17 am

    Hi Duarte,

    Yes, I think this method will work when using display:none;. I have yet to test it, but logically it makes sense. Such images are still loaded by the browser, yet not displayed to the user. Thus, the images will have been “preloaded”. A very elegant improvement indeed, Duarte — thank you! ;)

  6. Glad i could help Perishable, btw congratulations on the great website and articles you provide, i have learned a lot. Thank you.

  7. Thank you for this very useful post. I make ‘360 degrees virtual tours’ and had the problem that visitors had to wait for a more than 1 megabyte image to load after a change of scene. Now I have implemented your code, with the display:none command, without using an external css file, and the images load in a few seconds now!
    See the source of the link to one of my tours above.

    Thanx! And pls let me know if it works on all browsers, since I only have iexplorer 7 and the latest firefox..

  8. Jeff Starr
    Perishable 2008/05/07 8:56 am

    Sounds great, Vilmer — thanks for the feedback concerning your very practical application of the CSS-preloading technique. As for the cross-compatibility, I have not tested every browser on earth, but can definitely reassure you that the image-preloading method will work for a vast majority of your visitors. I think just about any modern browser (e.g., Firefox, Opera, IE7+, Safari, etc.) supports it.

  9. the best way i found actually is display:none; of course you should put a .htaccess file with these lines in your media online directory:

    ExpiresActive on
    ExpiresDefault "access plus 30 minutes"

    (ref:http://httpd.apache.org/docs/2.0/mod/mod_expires.html)

    now i try to cleanup some, the whole animation loading as long as it sometimes look a bit and rough ^^

    anyway with an infinite and unpredictable number of image to preload, i suggest to improve a bit this functionnality… (i’m actually trying to find how to catch an event like “all images are preload, display:block; the whole thing”)

    if you have ideas…

  10. Jeff Starr
    Perishable 2008/05/13 4:12 pm

    Careful with that htaccess, zjk! Setting default content expiration is great, so long as you specify expiration times for specific file types (e.g., .js, .css, .html, etc.) as needed. Depending on your needs, a default expiration value of 30 minutes may work fine for, say, images and flash files, but you may want to optimize performance by handling other file types differently.

  11. For hiding images it is possible to use z-index

  12. Jeff Starr
    Perishable 2008/05/14 8:29 am

    Ah yes, good call — thanks for the reminder :)

Comments are closed for this post. Something to add? Let me know.
Welcome
Perishable Press is operated by Jeff Starr, a professional web developer and book author with two decades of experience. Here you will find posts about web development, WordPress, security, and more »
.htaccess made easy: Improve site performance and security.
Thoughts
Dashlane recently redesigned, stating proudly that they "removed all filigree". They should have kept it, as the app now looks generic and boring.
Working on integration for setaPDF + EDD on the new books subdomain. Good times.
Toggle visibility of hidden files on Mac: Cmd + Shift + .
Great tool for checking browser caching for web pages and all included files.
The new minimalist design styled by 14KB of CSS (uncompressed and un-minified). That covers 850+ posts and pages spanning 15 years of diverse content.
Amazing (and sad) to think that, in the year 2020, Internet Explorer still doesn't support the placeholder attribute, which is supported by all other major browsers.
Finishing up with the latest redesign for Perishable Press! Should be live this week or early next.