A Way to Preload Images without JavaScript that is SO Much Better

by Jeff Starr on Saturday, June 14, 2008 27 Responses

Responding to my first attempt at preloading images without JavaScript, CSS-Guru David Bowman graces his audience with a most enlightening triage of comments.

Apparently, the image-preloading technique explained in the article is “major overkill” and “totally ridiculous.” Of course, I will be the first to admit that I am no expert in CSS, but I do enjoy sharing my discoveries and watching as people improve upon them. My first attempt at preloading images without JavaScript may indeed be “pretty crappy,” but it certainly works.

Fortunately, several weeks prior to Mr. Bowman’s dazzling performance, insightful reader Duarte helps the community by sharing a far more elegant solution using display: none;. Here is an example of its implementation:

Step 1 — Place this in your CSS file:

div#preload { display: none; }

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

<div id="preload">
   <img src="http://domain.tld/image-01.png" width="1" height="1" alt="Image 01" />
   <img src="http://domain.tld/image-02.png" width="1" height="1" alt="Image 02" />
   <img src="http://domain.tld/image-03.png" width="1" height="1" alt="Image 03" />
</div>

Once in place, this code will ensure that your images are preloaded and available for use elsewhere in the document. Just remember to call the displayed images using the same path as the the preloaded images. After that, everything should work perfectly. Indeed, even CSS-Wizard David Bowman “tested it out” and agrees that “the problem is solved.” Thanks for the confirmation, David! ;)

Alternatively, to avoid the extra (X)HTML markup, you may simply add background images to existing elements that are either dimensionless or empty. For example, to preload three images, image_01.png, image_02.png, and image_03.png, locate three appropriate elements in your markup and place something like this into your CSS file:


#element_01 {
	background: url(path/image_01.png) no-repeat;
	display: none;
	}
#element_02 {
	background: url(path/image_02.png) no-repeat;
	display: none;
	}
#element_03 {
	background: url(path/image_03.png) no-repeat;
	display: none;
	}

..and that should do it! For more information on this technique, check out this article: Pure CSS: Better Image Preloading without JavaScript. And who knows, if we’re lucky, maybe Mr. Bowman will once again grace us with his presence! ;)

About the author

[ Jeff Starr ]

Jeff Starr is a web developer, graphic designer and content producer with over 10 years of experience and a passion for quality and detail. Jeff is co-author of the book Digging into WordPress and strives to help people be the best they can be on the Web. + Follow Jeff on Twitter and subscribe to Perishable Press for awesome web-design content delivered fresh.


27 Responses
[ Gravatar Icon ]

David Bowman#1

Indeed, I’ve returned to comment once again.

First things first: I believe the word you were looking for is “triad,” not “triage.” It would only be a triage of comments if you were physically wounded by what I wrote, which is probably not the case, because you have a pretty forgiving attitude and you were humble enough not to delete my comments.

I just think there are too many bloggers in the world posting common sense techniques and thinking they found something new. And I suspect that this is just a tactic used to drive traffic to their sites. It just seems devious and wrong. Anybody with 10 seconds of CSS experience would have used “display: none” and not even bothered to blog about it. Maybe you did overlook it to begin with, but you seem like a pretty prolific blogger, so to me it just looked like a keyword-laden traffic-funnel post.

Anyway, in the interest of writing concise code, I really did think your original solution was overkill. You wrote a blog post about how Google’s homepage was terribly bloated. It might be bloated and inefficient, “but it works,” just like your first attempt at using CSS for preloading. Your “solution,” proportionally, just about as efficient as Google’s homepage vs. your XHTML version (i.e. about five times longer than necessary).

[ Gravatar Icon ]

Jeff Starr#2

Hi David, I appreciate the comment. I completely understand where you are coming from: the Web is polluted with a ton of garbage. I totally get the point, and continue to do my best to keep the content here at Perishable Press as “high-quality” as possible. I work very hard every day to produce content for this site and keep it running. Every cost is paid for entirely “out-of-pocket” — as you can see, I do not advertised on this site, and certainly derive no income from its existence. I have no interest in writing “keyword-laden traffic-funnel posts,” but rather try to learn as much as possible about my subject matter and post articles to share my discoveries. I may not be perfect, and I may make horrible and brainless mistakes from time to time, but I assure you that I am doing my best to represent myself as honestly, transparently, and sincerely as possible. This is the “real deal,” and will always be that way.
Regards,
Jeff

[ Gravatar Icon ]

Amos Wenger#3

This is addressed to David Bowman : I stumbled across Jeff’s page (first attempt) when I was searching a solution to this very simple problem : I had to preload images. So I created a div and styled it with display:none, and filled it with images. And then I fired Firefox 3 and oh magic it worked. When I went to test it with Opera, guess what ? Look, ma, no preloading :(. Seems that opera guys have over-optimized here. So the only practical and cross-browser solution (as sucky as it is), is effectively to move the div offscreen and leave it display:static. Mr Bowman, I suggest you to be less prompt to bash people in the head.

About accessibility and users having CSS disabled, I guess that.. if you have a webpage that requires image preloading, it is complex enough to “require” CSS to be enabled. It’s not as “bad” as to be browser-specific.

Finally, I’d like to congratulate Jeff for his website, looks great, loads fast, and has sound advice and intelligent+constructive comments.

[ Gravatar Icon ]

Jeff Starr#4

Thank you for the kind comments, Amos — they are greatly appreciated :)

[ Gravatar Icon ]

Amos Wenger#5

You’re welcome Jeff, and one more congrats for.. your ranking on Google. Funny enough, perishablepress.com came 2nd when I googled my name+surname just 3 hours after having posted here.

More on the "display:none = no preloading" issue, I’ve stumbled across a paragraph on the jqModal website (jquery plugin), which contains a more complete explanation and a (better?) workaround. See the “image caching” section at http://dev.iceburg.net/jquery/jqModal/ (no spam intended).

Also, apologies for repeating but to anyone reading that, if you’re having sound problems with Flash and display:none objects, read http://perishablepress.com/…/#comment-66277 and follow-ups.

[ Gravatar Icon ]

Jeff Starr#6

Hi Amos, that preloading method is interesting indeed. I will be looking into it further. As far as I can tell, the technique looks quite similar to the method described here, only with an explicit display:block declaration and the @import inclusion method. The block display property seems obvious (and redundant — divs are block elements to begin with), but the import directives are a mystery. i.e., why import the rules? What is the effect? Does it account for some of the preloading and Flash issues we’ve encountered? I need to check it.. ( thanks for pointing it out :)

[ Gravatar Icon ]

Amos Wenger#7

Hey Jeff, yes, the method is similar indeed, but the part that caught my eyes was the @media (and not @import, if of course we are talking about the same piece of css, and if my eyes aren’t faulty). I didn’t think about printing and this piece of code reminds me that.. moving images so far offscreen may cause serious printing problems, like many blank sheets and totally wrong layout. (Though it’s not exactly a piece of news that the web isn’t exactly printing-friendly).

Also I’d like to bring up an issue : if a page contains many high-resolution images to be loaded, the browser (tested, FF3/Linux and Opera 0.53/Linux) can stall while loading all the images. I was thinking that maybe a piece of javascript code could limit the number of simultaneous downloads, by writing progressively the “offscreen preloading divs” to the DOM, keeping progress by monitoring onload events on images. I don’t know if anyone is interested in that, though.

[ Gravatar Icon ]

Jeff Starr#8

Hi Amos, sorry for the delay — I am just now returning from a nice vacation and looking forward to getting back into things.

You are correct about the @media — that is what I meant to say (yes, we are looking at the same piece of code). I definitely like the idea of accounting for print stylesheets and will incorporate that method into the next relevant post.

I think the JavaScript solution you mention would be a worthwhile method for anyone doing a lot of heavy image preloading. Most of the preloading that I have been involved with deals with much less content, but that’s not to say that my next project won’t require preloading of that magnitude.

[ Gravatar Icon ]

Claudio#9

the best “preload images” option I’ve found!
TKS!

[ Gravatar Icon ]

kevin#10

Addressed to David Bowman: Do you have any blog so that I could write some nice comments? may be i could learn some techniques from your blog, like how to get real traffic to make money using blogs, without letting people know you are making money???

Hehe, Just a joke. Don’t take it seriously.

Oh, I like this preloading method. Thanks for the post.

[ Gravatar Icon ]

Jeff Starr#11

@kevin: My pleasure! Thanks for dropping by :)

[ Gravatar Icon ]

Mike P#12

Honestly (Mr. Bowman), I don’t see what your problem is with this site. The fact of the matter is that a lot of people looking for information on designing & developing websites are:

a) complete noobies who are probably searching google for this exact type of simple information that they might not have been aware of.

b) cant afford or have trouble learning from big thick textbooks & prefer to work from a “hands on” real-world experience approach searching for each piece of the puzzle they need separately, and then proceeding to implement in their own way.

As you can see, this is not a monetizing site — writing posts that generate a lot of search terms & rank in search engines is not sleazy. It generates a lot of hits because people are looking for this type of information. Since this site provides the information, and doesn’t trick them into clicking on monetizing links, I really don’t see what your qualms are.

I would like to continue to thank Mr. Starr on this excellent resource he has provided. I Originally came across this site about 6 months ago while searching for information about Wordpress Security. I am a basic/intermediate web designer/developer, and this site is, quite honestly, is one of the sites I go back to most often while looking for good, simple, information that I may have overlooked or when looking to learn something new that I don’t yet understand.

Maybe, once I have a few nice sites under my belt, I will post a linkback to my own site so you can see some of the material you helped me to create. Thanks a bunch & don’t pay to much attention to these haters.

[ Gravatar Icon ]

Jeff Starr#13

@Mike: Thank you — much appreciated :)

[ Gravatar Icon ]

Sheri Lee#14

Your website is creative, unusual, unique, beautiful. I’m motivated to finish the website I’m working on. I’m curious, how did you do the see-thru columns? I know how to make background fixed, but the columns are very clever. And how did you get the background? I’m in awe.

Sheri

[ Gravatar Icon ]

Jeff Starr#15

@Sheri Lee: Thanks for the kind remarks — much appreciated. The transparent columns are achieved with three different background images: one for the top, one for the bottom, and another that repeats for the height of the column. Each of these images is a 24-bit, alpha-transparent PNG file. Further, to optimize performance of the site, all three images are sewn together into a single “sprite” image. To see this, simply view the background image of any corner of any panel. For the site’s main background image, I spent some time in Photoshop 7 playing around with my “inspiring pattern” collection. After a couple of hours, the background began to emerge. I then spent some time fine-tuning the details to account for its intended use here at Perishable Press.

[ Gravatar Icon ]

Sheri#16

I found your site a few weeks ago while looking for a preload image solution and was awed by the design of your site (and still am) but had not read the other comments. Now I have — and I’m surprised to see intelligent people being so condescending. Is it the evil ‘IT ego’ that causes this? I’m just curious. I’ve worked in lots of IT departments and it seems to be the lurking place. I think, Jeff, that you handled Dave’s remarks very well. Maybe Dave didn’t intend to be intentionally rude but you have to be careful when you send text that doesn’t carry a smile, don’t you? I say keep up the great work, Jeff. This site is a work of art for the mind as well as the eye. Oh, one question, I didn’t know you could use 2 properties for one element — div class= and div id= (i peeked @ your source code). How does that work? Also, what is the value of importing CSS? I know you are busy, I’m patient and thanks for your time.

[ Gravatar Icon ]

Jeff Starr#17

Hi Sheri, I’m not sure what motivates people to leave bizarre comments, but I do know that I want to run a clean ship around here. It would have been easy for me to unleash a mountain of fury on that guy, but you know what? It wouldn’t have been worth it. Take the high(er) road, I always say.

For the CSS questions, yes you can use multiple classes on elements and even on elements that contain an id (only one id per element though). When classes are included on the same element as an id, the id properties will always override any of the class properties, if they exist. I often use ids to structure layout and then sprinkle a few classes around to accommodate styling.

As for importing the CSS, it all depends on your goals. As you may know, you can add CSS via inline styles, linked styles, or imported styles. Each one of these methods encompasses its own sphere of functionality, and includes its own pros and cons. For the most part, there is not much difference between linking and importing CSS styles. I think I used the latter in the case of the Quintessential theme in order to hide CSS from very old browsers.

[ Gravatar Icon ]

Jonathan Ellse#18

@Jeff

Ignore David. This site is completely awesome. It is now the first place I check when looking to sort a problem/integrate a new feature. Brilliant work again with this post.

[ Gravatar Icon ]

Jeff Starr#19

@Jonathan Ellse: Thanks for the positive feedback. People who take time to leave encouraging comments inspire me to stay focused and motivated to continue writing, creating, and sharing. There are millions of great blogs out there, so I am honored that you find mine worthy of your attention. Cheers :)

[ Gravatar Icon ]

Dave Stuttard#20

Hi, thanks for inviting me to this topic (I am currently posting to the 4G Blacklist one, but this one is also very enlightening! May I just concur all the good things people have said about this website and suggest that certain others try to avoid cluttering it up with banal comment.

I have discovered it and will certainly be consulting it profusely from now on for developing my modest web design skills (and my websites).

On this topic, I would only save a few seconds on my current websites if a scrolling Flash gallery of photos (a portfolio) could be preloaded - any ideas (preload the movie file or just the images)? This will be more significant when I display high-resolution photos.

By the way, it would be great if a directory full of images could be preloaded together using one short line of code - is this possible (to reduce the amount of repetitive lines of code)?

Any comments on these questions would be appreciated.

Thanks, Dave

PS: Sorry, but can two of my websites be removed from your records (I mistakenly entered them all when I registered) - when you hover or click on my name, all three are addressed together, resulting in nothing and someone might be daft enough to want a peak?

[ Gravatar Icon ]

Jeff Starr#21

@Dave Stuttard: I couldn’t agree more about avoiding “banal” comments! Some are tolerable, but thankfully I am blessed with an incredibly intelligent audience, so a majority of the comments are just straight-up awesome. :)

As for the Flash gallery, I would preload the content via Flash, especially if they won’t be shown otherwise. If a user has Flash, and is watching the movie, then preloading in the background will facilitate the usability of the experience. On the other hand, if you preload the images only and Flash is not available, you may be wasting bandwidth, processing power, and so on.

And, for preloading entire directories of images, it isn’t really possible using only a few lines of JavaScript, but with a little help from PHP, it is totally possible:

How to Preload an Entire Directory of Images Using Javascript and PHP

Preloading images from a directory

Regards,
Jeff

PS: I removed as many of the extraneous URLs from your author links as possible. Let me know if I missed any!

[ Gravatar Icon ]

James#22

Hello,

Great bit of CSS, but it only works for me in internet explorer (version 6) using fusion for mac with old install of XP for testing.

Does not work on latest safari or firefox (mac)

Thanks.

oh the *images* should be before or after

[ Gravatar Icon ]

Dave#23

Or, if the preloader is for an AJAX load, simply stick the image inside the element, then replace it in the callback function you’re surely calling when the data finishes loading. No-mess instant loader that works every time.

[ Gravatar Icon ]

David Winstead#24

Your CSS trick worked for me where I needed to preload images for a javascript slideshow on a site I’m building… I only checked it in Firefox, and images appear instantly! Thank You and keep up the good work!!

[ Gravatar Icon ]

Jeff Starr#25

Awesome, Dave — great to hear it! Thanks for the positive feedback :)

Trackbacks / Pingbacks
  1. Preloading Images with JavaScript or CSS « Patrick Gates’s Blog
  2. Shiba » Rotating WordPress Header
Comments are closed for this post

If you have or need further information, contact me.



Attention: Do NOT follow this link!