css · geeky · php code

Lazy image placeholders that respect the actual image aspect ratio

While lazy loading of the images has been used by many performance conscious websites, the placeholder images are not usually the focus. Having placeholder images that respect the actual proportion of the lazily loaded images will reduce the “jumpiness” once images are loaded.

Obviously in order to do this, you will need to know the actual image dimensions prior to the image loading. In my case, we have an easy way to get the width and height of the images server side. Therefore I want to know if I could create better placeholders for our lazily loaded images.

In order to improve performance, we often set the placeholder image src to a 1×1 gif data uri or nothing.

Originally I thought as long as a image has the appropriate width and height attributes and the max-width: 100%; height: auto; css property, it would automatically adjust itself based on the width and height attribute proportion inside a container. This is not the case.

It seems what the browser honors is not what you set in the attributes but the actual size of the image.

  • If you do not set the src attribute, there will not be a height defined.
  • If you use a 1×1 gif data uri such as data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==, it will resize based on a square ratio.

Now you may use javascript to calculate the ratio and set a inline style attribute to with the explicit width and height. This method is not robust and costly. You would have to recalculate each time the container size changes. I want to seek a non javascript solution to this problem.

This thread has discussed a solution by using padding-top. I’ve seen this used in various places before and it seems to be the best bet. Although it suggested it would require a wrapper around all images, I want to attempt a solution without the wrapper none of the lazy image loader expects your images to have wrapper elements.

Here’s the solution I came up with.

You’d calculate the padding-top on the server side with the known width and height of the image. Something that may look like:

if (!empty($variables['width']) && !empty($variables['height'])) {
    $ratio = $variables['height'] / $variables['width'];
    $padding_top = ($ratio * 100) . '%';
    $image['#attributes']['style'] = 'width: '. $variables['width'] .'px; height: 0; padding-top: ' . $padding_top . ';';

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s