Spring Sale! Save 30% on all books w/ code: PLANET24
Web Dev + WordPress + Security

Better Image Caching with CSS

[ CSS3 ] I have written previously on the fine art of preloading images without JavaScript using only CSS. These caching techniques have evolved in terms of effectiveness and accuracy, but may be improved further to allow for greater cross-browser functionality. In this post, I share a “CSS-only” preloading method that works better under a broader set of conditions.

Previous image-preloading techniques target all browsers, devices, and media types. Unfortunately, certain browsers do not load images that are hidden directly (via the <img> element) or indirectly (e.g., via the parent <div> element) using either display:none; or visibility:hidden;. Further problematic is the potential unintentional display of images on pages when presented via specifically designed print stylesheet.

To get around these limitations, we begin by segregating our strategy to target different media types. For example, for web pages featuring both screen and print stylesheets, we treat each separately by writing this:

@media screen {}
@media print {}

Then, to ensure that the images are preloaded in all browsers, we need to avoid the use of either display:none; or visibility:hidden; in the method. Rather than risking non-caching by hiding or preventing the display of images that need preloaded, we ensure their display and position them far outside of the screen. To do this, we enclose all images that need cached within some specifically identified division like so:

<div id="preloader">
	<img src="http://domain.tld/path/images/01.png" width="1" height="1" />
	<img src="http://domain.tld/path/images/02.png" width="1" height="1" />
	<img src="http://domain.tld/path/images/03.png" width="1" height="1" />
	<img src="http://domain.tld/path/images/04.png" width="1" height="1" />
	<img src="http://domain.tld/path/images/05.png" width="1" height="1" />
	<img src="http://domain.tld/path/images/06.png" width="1" height="1" />
	<img src="http://domain.tld/path/images/07.png" width="1" height="1" />
</div>

Then, with that markup in place, we flesh out the previous media directives with the following CSS:

@media screen {
	div#preloader {
		position: absolute;
		left: -9999px;
		top:  -9999px;
		}
	div#preloader img {
		display: block;
		}
	}
@media print {
	div#preloader, 
	div#preloader img {
		visibility: hidden;
		display: none;
		}
	}

Here, we have the preloader division positioned far to the lower-left outside of the screen, and then redundantly specify block display on the image elements.

Finally, to prevent the unwanted display of these preloaded images via print media, we simply hide the images via display:none; and visibility:hidden; declarations.

When using this method to preload/cache images, remember to call the preloaded images by using the exact same path used for the original preloaded image. For caching to work, the browser must reference an existing resource via the identical path.

This method is designed to enable the caching of specified images in virtually all visual browsing devices. If you encounter cases where this method does not work, or if you have comments or suggestions for improvement, please share by leaving a comment below. Thanks!

About the Author
Jeff Starr = Web Developer. Security Specialist. WordPress Buff.
.htaccess made easy: Improve site performance and security.

45 responses to “Better Image Caching with CSS”

  1. Jeff Starr 2010/05/02 1:33 pm

    Hi Bahrul, thanks for the feedback! :)

  2. Hi
    thank you.
    Worked !

  3. Horrible site for scrolling down. Not a good ad for a web sdesigner.

  4. Hi Robert,

    Thanks for the useful input. After some help from other visitors, it looks like scrolling is working smoothly again for everyone. Please refresh your browser and let me know if any further issues. Thanks.

  5. thank you so much! this solved my problem.

  6. Personally i prefer to use the JQuery LazyLoad plugin if my page is image intensive. (big images you need to scroll to) that way the images are only loaded when you need them.

    Preloading images tends to slow down the response. Also using CSS image sprites is way more efficient than loading hidden images for things like menus

  7. Elisandro 2011/08/12 3:10 pm

    Unfortunately, I couldn’t make it work… I’ve tryed a thousand tutorials, but nothing happens. I want to load an image 1024×739 at once, without cutting the image. Can someone help me out, pleaaase?

    Thanks Jeff, for your great blog!

  8. Just wanted to Thank You for posting this – Helped me out so much. Had never thought of preloading images like this!!

    Thanks again –

  9. Jeff Starr 2011/09/29 1:31 pm

    My pleasure, Trent – Thanks for the feedback :)

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 »
The Tao of WordPress: Master the art of WordPress.
Thoughts
I live right next door to the absolute loudest car in town. And the owner loves to drive it.
8G Firewall now out of beta testing, ready for use on production sites.
It's all about that ad revenue baby.
Note to self: encrypting 500 GB of data on my iMac takes around 8 hours.
Getting back into things after a bit of a break. Currently 7° F outside. Chillz.
2024 is going to make 2020 look like a vacation. Prepare accordingly.
First snow of the year :)
Newsletter
Get news, updates, deals & tips via email.
Email kept private. Easy unsubscribe anytime.