Responsive Images with Correct Aspect Ratios — Prevent Layout Shifts
Images without explicit dimensions cause layout shifts (CLS). Here's how to prevent reflow using aspect-ratio, width/height attributes, and modern responsive image techniques...
Images without explicit dimensions cause Cumulative Layout Shift (CLS) — the page jumps when images load. Google’s Core Web Vitals measure CLS and it affects SEO rankings. Setting correct aspect ratios prevents this.
Use the Aspect Ratio Calculator to calculate the right dimensions for your images.
Why images cause layout shifts
When a browser renders this HTML:
<img src="photo.jpg" alt="A photo">
It doesn’t know the image dimensions until the file loads. The page allocates zero height, then jumps when the image arrives — that’s the layout shift.
Solution 1: width and height attributes
The simplest fix — add width and height attributes matching the natural image size:
<img src="photo.jpg" alt="A photo" width="800" height="600">
Modern browsers use these to compute the aspect ratio before the image loads, reserving the correct space. The actual display size is controlled by CSS, but the ratio is preserved.
/* Image will still be responsive: */
img {
max-width: 100%;
height: auto;
}
This is the recommended approach. It works in all browsers.
Solution 2: CSS aspect-ratio
img {
width: 100%;
aspect-ratio: 4 / 3; /* matches your image ratio */
object-fit: cover;
}
Or with a wrapper:
.image-wrapper {
width: 100%;
aspect-ratio: 16 / 9;
overflow: hidden;
}
.image-wrapper img {
width: 100%;
height: 100%;
object-fit: cover;
}
Solution 3: padding-top hack (old way)
Still used for maximum browser compatibility, but aspect-ratio is preferred:
.image-wrapper {
position: relative;
padding-top: 56.25%; /* 9/16 = 56.25% for 16:9 */
}
.image-wrapper img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
Next.js Image component
Next.js’s <Image> handles this automatically:
import Image from 'next/image';
// Required: width and height define the aspect ratio
<Image
src="/photo.jpg"
alt="A photo"
width={800}
height={600}
/>
// For responsive fill:
<div style={{ position: 'relative', height: '400px' }}>
<Image
src="/photo.jpg"
alt="A photo"
fill
style={{ objectFit: 'cover' }}
/>
</div>
Next.js automatically:
- Adds width/height to prevent CLS
- Generates WebP/AVIF variants
- Lazy loads by default
- Adds
sizesattribute for responsive images
Astro Image component
---
import { Image } from 'astro:assets';
import myPhoto from '../assets/photo.jpg';
---
<Image src={myPhoto} alt="A photo" />
<!-- Automatically includes correct width, height, and format -->
srcset and sizes for responsive images
For truly responsive images that load the right size:
<img
src="photo-800.jpg"
srcset="
photo-400.jpg 400w,
photo-800.jpg 800w,
photo-1200.jpg 1200w
"
sizes="
(max-width: 600px) 100vw,
(max-width: 1200px) 50vw,
800px
"
width="800"
height="600"
alt="A photo"
loading="lazy"
>
The width and height attributes are for the natural image dimensions (the largest src). The browser uses them to compute the aspect ratio.
Calculating aspect ratios for your images
For an 800×600 image:
- Ratio = 800:600 = 4:3
- For a 1000px wide container: height = 1000 × (600/800) = 750px
- Padding-top percentage = 600/800 × 100 = 75%
function getAspectRatio(width, height) {
const gcd = (a, b) => b ? gcd(b, a % b) : a;
const divisor = gcd(width, height);
return `${width / divisor}:${height / divisor}`;
}
function getPaddingPercent(width, height) {
return (height / width * 100).toFixed(4) + '%';
}
getAspectRatio(1920, 1080) // "16:9"
getAspectRatio(800, 600) // "4:3"
getPaddingPercent(16, 9) // "56.2500%"
Common ratios for different content
| Content Type | Ratio | Padding % |
|---|---|---|
| Widescreen video | 16:9 | 56.25% |
| Standard video/TV | 4:3 | 75% |
| Square (Instagram) | 1:1 | 100% |
| Portrait photo | 3:4 | 133.33% |
| Landscape photo | 3:2 | 66.67% |
| Mobile portrait | 9:16 | 177.78% |
| Banner/hero | 3:1 | 33.33% |
| Product card | 4:5 | 125% |
Related tools
- Aspect Ratio Calculator — calculate pixel dimensions
- Aspect Ratio Guide — common ratios explained
- CSS aspect-ratio Property — modern CSS approach
Related posts
- Aspect Ratios Explained: A Complete Guide for Developers and Designers — Every major aspect ratio, what it's used for, and the CSS techniques for maintai…
- Aspect Ratio Calculator — Calculate Width, Height, and Ratios — An aspect ratio calculator finds missing dimensions when you know the ratio and …
- Aspect Ratio Guide — Common Ratios for Video, Images, and UI Design — Aspect ratio is the proportional relationship between width and height. Here's a…
- CSS aspect-ratio Property — Maintain Proportions Without Padding Hacks — The CSS aspect-ratio property sets a preferred aspect ratio for elements. No mor…
Related tool
Calculate aspect ratios (16:9, 4:3, 21:9, etc.). Given W:H and one dimension, get the other. Responsive padding-top % for CSS aspect-ratio containers.
Written by Mian Ali Khalid. Part of the Frontend & Design pillar.