DEV Community

Yaser Adel Mehraban
Yaser Adel Mehraban

Posted on • Originally published at yashints.dev

Image aspect ratio done right 😍

If you have an image on a page which is 600x200 pixels, chances are it's not going to be shown exactly with that size. That's because most of the time it's put inside a container which defines the width and the image is set to width: %100. But the size of the image is not that important at this point, what is important is that you will have a DOM reflow once the image is loaded. It's not clear enough? Let's go through it by an example.

Problem

Let's see this in action. I'll use Glitch to quickly whip up a demo. We need three divs, two of those contain a piece of text and the one in between contains an image.

<head>
  <title>Image aspect ratio</title>
  <style>
    .image-container {
      width: 500px;
    }

    img {
      width: 100%;
    }
  </style>
</head>
<body>
  <h1>Image aspect ratio done right</h1>

  <div >
    <p>
      This is the first bit of text here!
    </p>        
  </div>

  <div class="image-container">
    <img src="https://www.hindustantimes.com/rf/image_size_960x540/HT/p2/2018/09/08/Pictures/_7ae928c8-b34e-11e8-bb15-a1f88311a832.jpg"
          width="960" height="540"/>
  </div>

  <div>
    <p>
      This is the second bit of text here!
    </p>  
  </div>
</body>
Enter fullscreen mode Exit fullscreen mode

You can see the full page in this Glitch app.

If we load the site under a slow network now (on high speed network you can't see much of a difference), you will the page load like this:

Page loads with text first close together, then image loads and fills the gap

First the two paragraphs appear close to each other, then when the network request is finished, the image fills its gap and there is a DOM reflow performed to push the second paragraph down. How sad is that πŸ˜₯?

Solution #1

The very first thing we can do is to simply set the image height to auto. This is a new feature which has landed in FireFox and Chrome. This will tell the browser to find out the metadata from image attributes, calculate the necessary height and reserve that space. So all we need to do is this:

<style>
  img {
    width: 100%;
  }
</style>
Enter fullscreen mode Exit fullscreen mode

And we we reload the page on the same network, you can see the page load like this:

Page loads with text first with enough vertical distance between them based on image aspect ratio, then image loads and fills the gap

How good is that 😍?

Solution #2

There is a new proposal in a draft state which is introducing a new CSS property called, well aspect-ratio. With this you can simply add the property to img tag and use the width and height attributes to tell the browser how much space should be reserved.

img {
  aspect-ratio: attr(width) / attr(height);
}
Enter fullscreen mode Exit fullscreen mode

This has the benefit of being super simple, readable, and supporting most of the images on the web because many people already have put width and height attributes on their images.

On the other hand, a junior developer who's starting with HTML and CSS doesn't have any trouble understanding what's happening and how little should be done to do something properly.

This has been implemented in Firefox, Chrome and Edge.

Summary

Getting image aspect ratio is very important especially if it impacts your site's user experience. So knowing how to fix that issue is also important. Hope you've enjoyed this article and till next time πŸ‘‹πŸΌ.

Top comments (3)

Collapse
 
teresaholfeld profile image
Teresa Holfeld

I don't understand solution 1. What do I have to change? Delete the other class in the css?
You are also talking about the auto keyword. Shouldn't I use that in the css?

Collapse
 
yashints profile image
Yaser Adel Mehraban

Solution one is basically adding height:auto; to the image tag and setting the proper aspect ratio. Say the ratio was 800x600 if you set that right, the image will gets resized by its parent correctly, plus the fact that on load browser will calculate how much height it should reserve for the image and render other elements while its loading

Collapse
 
ben profile image
Ben Halpern

Nice!