Placeholder background/image while waiting for full image to load?

I have a few images on my page. I’m finding that the page starts to render before the images have been loading (which is good), but that the visual effect is not great. Initially the user sees this:

 --------hr--------
 text

Then a few milliseconds later the page jumps to show this:

--------hr--------
[           ]
[   image   ]
[           ]
text

Is there a simple way that I can show a grey background image of exactly the width and height that the image will occupy, until the image itself loads?

The complicating factor is that I don’t know the height and width of the images in advance: they are responsive, and just set to width: 100% of the containing div. This is the HTML/CSS:

<div class="thumbnail">
<img src="myimage.jpeg" />
<div class="caption">caption</div>
</div>
img { width: 100% } 

Here’s a JSFiddle to illustrate the basic problem: http://jsfiddle.net/X8rTB/3/

I’ve looked into things like LazyLoad, but I can’t help feeling there must be a simpler, non-JS answer. Or is the fact that I don’t know the height of the image in advance an insurmountable problem? I do know the aspect ratio of the images.

Instead of referencing the image directly, stick it within a DIV, like the following:

<div class="placeholder">
    <div class="myimage" style="background-image: url({somedynamicimageurl})"><img /></div>
</div>

Then in your CSS:

.placeholder {
    width: 300;
    height: 300;
    background-repeat: no-repeat;
    background-size: contain;
    background-image: url('my_placeholder.png');
}

There is a really simple thing to check before you start looking into lazy-loading and other JS.
Make sure the JPG images you are loading are saved with the ‘progressive’ option enabled!
This will cause them to load the image iteratively, starting with a placeholder that is low-resolution and faster to download, rather than waiting for the highest res data before rendering.

The only thing I can think of, to minimize the jump effect on your text, is to set min-height to where the image will appear, I would say – set it to the “shorter” image you know of. This way the jump will be less evident and you won’t need to use lazyLoad or so… However it doesn’t completely fix your problem.

I had the same issue with my responsive website. My solution was to fade in the page using jquery. Technically you’d want to do the fade onload so all the images are loaded, but using ready sufficed in my case.

Specifically:

body { display: none; }

and

$(document).ready(function() {
    $('body').fadeIn();
});

If your images take a while to load, then lazily load them.

Here’s one naive way of doing it,

img {
box-shadow: 0 0 10px 0 rgba(#000, 0.1);
}

You can manipulate the values, but what it does is it creates a very light border around the image that doesn’t push the contents. Images can load at whatever time they want, and you get a good user experience.

Hope that it helps