Latest TweetsDifference between mod_alias and mod_rewrite…
Perishable Press

Better Image Caching with CSS

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" />

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 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!

Jeff Starr
About the Author Jeff Starr = Web Developer. Security Specialist. WordPress Buff.
45 responses
  1. Jeff Starr

    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. Jeff Starr

    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. Rob Lynch June 22, 2011 @ 11:24 am

    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. 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

    My pleasure, Trent – Thanks for the feedback :)

[ Comments are closed for this post ]