aspect-ratio property. This guide shows production patterns, accessibility tips, and a tiny fallback so your layout stays predictable and responsive—with fewer hacks and less layout shift (CLS).
Why aspect ratio matters in responsive design
Responsive layouts break when heights collapse or media crops unpredictably. Declaring a CSS aspect ratio guarantees the element’s height scales from its width—preventing layout jumps and keeping your design consistent across viewports.
Tip: for quick calculations or prototyping, try an Aspect Ratio Calculator to convert between sizes while preserving proportion.
The modern solution: aspect-ratio
.card {
aspect-ratio: 16 / 9; /* width / height */
width: 100%;
background: #f6f7f9;
border-radius: 12px;
}
- Squares:
aspect-ratio: 1 / 1 - Landscape cards/videos:
16 / 9 - Vertical previews:
9 / 16
Responsive images: cover vs contain (no CLS)
Use aspect-ratio to reserve space, and object-fit to control how the image fills that space. Also add width and height attributes to each <img> to let the browser infer the ratio immediately and avoid CLS.
<div class="media media--16x9">
<img src="landscape.jpg" alt="Mountain lake at sunrise" width="1600" height="900" loading="lazy">
</div>
.media { aspect-ratio: 16 / 9; border-radius: 12px; overflow: hidden; }
.media > img {
width: 100%;
height: 100%;
object-fit: cover; /* crop excess to fill the box */
display: block;
}
Use object-fit: contain for UI diagrams or charts where cropping is unacceptable (letterboxing may appear).
Responsive video & iframes (YouTube, Vimeo, maps)
Option A: Set ratio on the iframe
<iframe
class="video"
src="https://www.youtube.com/embed/VIDEO_ID"
title="Video title"
allowfullscreen
loading="lazy"></iframe>
.video {
aspect-ratio: 16 / 9;
width: 100%;
border: 0;
border-radius: 12px;
}
Option B: Wrapper pattern (handy for overlays)
<div class="video-wrap">
<iframe src="https://www.youtube.com/embed/VIDEO_ID" title="Video title" allowfullscreen loading="lazy"></iframe>
</div>
.video-wrap { aspect-ratio: 16 / 9; position: relative; }
.video-wrap > iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
CSS Grid galleries with consistent tiles
<ul class="grid">
<li class="tile"><img src="1.jpg" alt="Gallery item 1" width="1200" height="1200" loading="lazy"></li>
<li class="tile"><img src="2.jpg" alt="Gallery item 2" width="1200" height="1200" loading="lazy"></li>
<li class="tile"><img src="3.jpg" alt="Gallery item 3" width="1200" height="1200" loading="lazy"></li>
</ul>
.grid {
display: grid;
gap: 12px;
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
}
.tile {
aspect-ratio: 1 / 1; /* perfect squares */
border-radius: 12px; overflow: hidden; background: #eee;
}
.tile > img { width: 100%; height: 100%; object-fit: cover; display: block; }
Swap 1 / 1 for 3 / 4, 2 / 3, or 4 / 3 to change the gallery’s vibe.
Flexbox cards that keep their shape
.cards { display: flex; gap: 16px; flex-wrap: wrap; }
.card { flex: 1 1 260px; aspect-ratio: 4 / 3; border-radius: 14px; background: linear-gradient(#fafbfc, #f2f3f5); }
Dynamic aspect ratios with CSS variables
<div class="ratio" style="--w: 21; --h: 9;" aria-label="21 by 9 box"></div>
<div class="ratio" style="--w: 3; --h: 4;" aria-label="3 by 4 box"></div>
.ratio {
aspect-ratio: var(--w) / var(--h);
background: #f8fafc;
border: 1px dashed #d6dae1;
border-radius: 12px;
}
Cap hero height while preserving ratio
.hero {
aspect-ratio: 21 / 9;
width: 100%;
height: min(70vh, 680px); /* cap height on tall screens */
}
If you set both width and height explicitly, the element keeps that size; aspect-ratio then acts as a preferred ratio during layout.
Fallback for older browsers
.ratio { aspect-ratio: 16 / 9; }
/* Only if aspect-ratio is not supported */
@supports not (aspect-ratio: 1 / 1) {
.ratio { position: relative; }
.ratio::before {
content: "";
display: block;
padding-top: calc(9 / 16 * 100%); /* height / width as percentage */
}
.ratio > * { position: absolute; inset: 0; }
}
Common pitfalls (and fixes)
- Mixing
min-heightwithaspect-ratio: prefermax-heightorheight: min(...). - Expecting
object-fitto set the container ratio: it only controls how media fits inside. - Rounded corners not clipping images: add
overflow: hiddento the container. - CLS from images: include
width/heightattributes or putaspect-ratioon the container. - Nested ratios collapsing: ensure the parent defines height via ratio before sizing children to
height: 100%.
Copy-paste utility classes
/* Quick utilities */
.ratio-1x1 { aspect-ratio: 1 / 1; }
.ratio-4x3 { aspect-ratio: 4 / 3; }
.ratio-3x2 { aspect-ratio: 3 / 2; }
.ratio-16x9 { aspect-ratio: 16 / 9; }
.ratio-9x16 { aspect-ratio: 9 / 16; }
/* Media helpers */
.fit-cover { width: 100%; height: 100%; object-fit: cover; display: block; }
.fit-contain { width: 100%; height: 100%; object-fit: contain; display: block; }
.rounded-12 { border-radius: 12px; overflow: hidden; }
Common aspect ratios (and legacy padding)
| Ratio | CSS | Legacy padding-top | Use case |
|---|---|---|---|
| 1:1 | aspect-ratio: 1/1 |
100% | Avatars, square tiles |
| 4:3 | 4/3 |
75% | Classic photos, cards |
| 3:2 | 3/2 |
66.6667% | Editorial images |
| 16:9 | 16/9 |
56.25% | Video, hero banners |
| 9:16 | 9/16 |
177.7778% | Reels, vertical stories |
SEO & performance checklist
- Declare
aspect-ratioon media wrappers and cards to reserve height. - On
<img>, set accuratewidth/heightattributes to cut CLS. - Use
loading="lazy"for below-the-fold images/iframes. - Use descriptive
alttext; never stuff keywords. - Add a progressive fallback via
@supports not (aspect-ratio: 1 / 1). - Cap extremes with
min()/max()/clamp()to avoid overflow on unusual screens. - Test at multiple breakpoints and on low-end devices for jank.
FAQs
What is the simplest way to keep a video responsive?
Set aspect-ratio: 16/9 on the iframe (or wrapper) and width: 100%, add loading="lazy" and a descriptive title for accessibility.
Should I use object-fit: cover or contain?
Use cover for thumbnails and hero images (cropping edges is fine). Use contain for UI/diagrams where everything must be visible.
Do I still need the padding-top hack?
Only for very old browsers. Provide it conditionally with @supports not (aspect-ratio: 1 / 1).
Can I limit hero height while keeping ratio?
Yes: height: min(70vh, 680px); aspect-ratio: 21/9; caps height on tall screens while staying responsive.
Does aspect-ratio work in Grid and Flex layouts?
Yes. The layout defines the width; the browser computes height from the ratio, keeping tiles consistent across rows.
Conclusion
For a truly CSS aspect ratio responsive layout, use the aspect-ratio property wherever you previously relied on hacks—cards, media, tiles, and embeds. Combine it with object-fit, set image dimensions to prevent CLS, and include a small fallback for legacy browsers. You’ll get cleaner code, smoother rendering, and a UI that scales beautifully across devices.