Responsive images and preventing page reflow

  • 6 Min. Read.

While developing the new website for CodeCaptain, we were looking at ways to prevent article pages from reflowing (jumping) when our responsive images loaded.

Prevent reflow by specifying width and height

The first (and most obvious) way to prevent reflow is to pass in the width and height of the image as attributes.

In this case, the browser will reserve a block of 100×100 pixels, in order to prevent the page from jumping around when the image loads. This way works great, but has a major drawback: it’s not responsive.

Well.. then just don’t define the height and give it a max-width, right?

Wrong. When you don’t specify the height (height: auto) and only give the image a max-width, the image will become responsive, but since there’s no height specified, the page will jump when the image is loaded, so using max-width on the image without specifying the height was not ideal.

Creating a container for our responsive images that reserves space on the page

Using a nifty padding-bottom trick, we were able to reserve space on the page by looking at the aspect ratio of the responsive images, let me give you an example.

When you have an image measuring 160×90, you have an aspect ratio of 16/9 (or 1.777777778). By knowing this aspect ratio, you can calculate the height of an image, by only knowing about the width.

In this case, the height of the image will be the width / aspect, or to put it easy: for every 16 pixels of width, the image has 9 pixels of height.

  • Width 16px: height 9px
  • Width 32px: height 18px
  • Width 9000px: height 5062.5px

We’ll always know the width of the responsive images (100% of the container), so we’re going to calculate the height of the image, which is going to be 9/16 or 56.25% of the width.

Knowing this, we can assign a value of 56.25% to the padding-bottom of our responsive container. We’ll then add in the image, positioned absolute at 100% of the width and 100% of the height.

And the HTML looks like this:

I added in a placeholder image sized at 3200×1800 and put it in a pen, take a look:

To prevent the responsive images from getting scaled beyond its original size, we wrapped the responsive container in an image-wrapper, with a max-width and max-height of 3200px and 1800px.

Testing if the page reflows

Obviously, you want to test how these images affect the loading of the page, but how would you do that? Your internet connection is probably pretty fast, so the images will load instantly, how would you test a slow connection?

Chrome network throttler

In the Chrome devtools there’s a handy option called the network throttler. To use it, you want to open the devtools, switch to the network tab and click the throttling option.

Open the devtools, switch to network and click the throttling dropdown
Open the devtools, switch to network and click the throttling dropdown

In here you get a wide range of network conditions, you can choose whichever you like, just make sure you test on a wide variety of conditions, instead of a single one.

Select box with available network conditions, test on a wide variety
Select box with available network conditions, test on a wide variety

Finally, reload the page, and you’ll notice that it becomes considerably slower. You’ll see the image starts to load, but the container has the entire space reserved on the page, that’s the result we’re after!

Loading on a slow connection, notice the entire space is reserved in the page by the responsive images container
Loading on a slow connection, notice the entire space is reserved in the page by the responsive images container

Resize your browser window and you’ll see that the reserved space matches the image exactly on every viewport width!

Dynamically calculating the aspect

In the example above we talked about the image with a 16/9 aspect ratio and we hard-coded these values in the CSS, but in reality your images will have various different aspects, so it’s pretty impossible to define every aspect in CSS.

Using PHP

We’ll end this blog post with an example on how to implement dynamic responsive images using the tricks explained above.

PHP has a built-in function called getimagesize and it returns an array with the width and height of the image.

To calculate the aspect dynamically, do the following:

And then, we want to output the structure and image in our HTML:

And there we have it, our dynamic responsive image which won’t cause a reflow when it loads. Enjoy!

A concept by Wonderlus

Warning: Parameter 1 to W3_Plugin_TotalCache::ob_callback() expected to be a reference, value given in /mnt/home_bingo/codecaptain/codecaptain.io/public/wp-includes/functions.php on line 3583