To work on CLS of Core Web Vitals, I needed to find a way to set height of img
tag when an image is 100% width on the screen, since the height of the image changes whenever the window is resized. The site I was working on was built on WordPress and found the workaround. So, I will write how to manage it on WordPress.
A more universal way of doing what OP asked is to simply set a width and height on an image in pixels using the native width
and height
attributes.
This is what is advised as the modern best practice
Assuming that the browser has all the information it needs to calculate the width (from inlined CSS) modern browsers will then allocate enough space for the image to avoid a layout shift.
These width and heights do not have to be the actual size the image will display, just the correct proportions.
So in the below example we grab the width and height of the image thumbnail (say 640px wide and 480px high).
Then we set the width of the image in CSS relative to it's container (so in this example 50% of the page width).
The browser will then allocate the correct height for the image to avoid a layout shift. (in the below example it would allocate 720px height assuming the screen width is 1920px - a 960px wide image due to 50% width and then a height of 720px to retain the aspect ratio.)
$img = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ) , 'thumbnail' );
$src = $img[0];
$height = $img[1]; //e.g. 640(px)
$width = $img[2]; //e.g. 480(px)
<style>
img{
width: 50%;
height: auto; /*this is important as otherwise the height set on the image will be used*/
}
</style>
<img src="<?php echo $src; ?>" width="<?php echo $width; ?>" height="<?php echo $height; ?>" />
In the below fiddle I load a large image (you may still want to add throttling to see there is no layout shift). The space is automatically calculated by the browser so no layout shift occurs.
The big advantage is the below works with media queries (as you can set any width in the inline CSS) and will work correctly with a Content Security Policy as it doesn't rely on inline style
items.
<style>
img{
width: 50%;
height: auto;
}
</style>
<img src="http://picserio.com/data/out/369/sahara-desert-wallpaper_5757536.jpg" width="6400" height="4800" />
<p>I don't shift</p>