Lazy loading with "responsive" images (unknown height)

Even cleaner:

  1. Set height and width of images to an arbitrarily-large number (like 2000px x 1000px)
  2. Apply the following CSS to each of the desired images (perhaps via a shared class):
    max-width: 100% and height: auto
  3. Smile wide :)

Credit for this approach goes to Github user dryabove, given in this Github issue


Here's the more elegant solution, from the comments. It still requires writing the aspect ratio server side, but with a wrapper div:

<div class="lazy"><img src="foo.jpg" style="max-width:100%" data-aspect="0.75" /></div>

Then with JS I give the wrapper div a padding-bottom:

$('div.lazy').livequery(function() {
    var c = $(this);
    var r = c.data('ar');
    c.css('padding-bottom', r * 100 + '%');
});

This gives the div the exact dimensions that the img will eventually consume. I then use the following LESS to load the image within the area the padding consumes:

div.lazy {
  max-width:100%;
  position:relative;
  img {
    position:absolute;
    width:100%;
    height:100%;
  }
}

I had a similar problem recently, combining Isotope with Lazy Load in a responsive layout. Isotope determines the layout based upon the width and height of the images when the page is loaded, so initially, the items were all overlapping because Isotope wasn't calculating the correct size.

To make sure the placeholder items were saving the space, I used the padding-bottom trick you mentioned: http://thisisthat.co.uk/notebook/2013-10-07-lazy-loading-responsive-images (Though it may have not been that exact post.) Here's my markup:

    <article class="portfolio-item">
        <a class="portfolio-link" href="img/gallery/thumb90.jpg" style="padding-bottom: 66.2%">
            <div class="portfolio-image-wrapper">
                <img class="portfolio-image" data-original="img/gallery/thumb90.jpg" width="1000" height="662">
            </div>
            <div class="portfolio-text">
                <h1 class="portfolio-item-name">
                    <span href="#" class="icon" data-icon="e"></span>
                    <span class="portfolio-item-tags">Bridals</span>
                </h1>
            </div>
        </a>
    </article>

That's probably more involved than you need (as the entire .portfolio-text div is an overlay which has quite a bit of styling going on). The real key was just in calculating the bottom padding based upon the width and height of the image (which I did in the template with PHP) and setting that as the padding-bottom of the item that I wanted to save the space.