Problem Solved

CSS · aspect-ratio

Home › Courses › CSS › Problems › aspect-ratio
🎨 Concept · 3 min read

aspect-ratio.
Fixed ratios, no padding hacks.

Before 2021, keeping an element at a 16:9 ratio required a padding-top: 56.25% hack, a positioning trick, and a wrapper element. Now it's one property: aspect-ratio: 16 / 9. Works on images, videos, iframes, cards, containers — any element with a width. This page covers the syntax, the patterns, the object-fit relationship, and the four things that break it.

Short answer: Use aspect-ratio: 16 / 9 on a container or media element to fix its width-to-height ratio. Combine with object-fit: cover on images and videos to crop them into the fixed shape. Combine with width: 100% to make it responsive. Set width and height HTML attributes on to prevent layout shift. aspect-ratio sets the shape; object-fit fits the content.

✅ Basic usage

One property, any ratio.

aspect-ratios.css
/* 16:9 — video, YouTube embeds, hero sections */
.widescreen {
aspect-ratio: 16 / 9;
width: 100%;
}

/* 4:3 — old-school TVs, product photos */
.standard {
aspect-ratio: 4 / 3;
width: 100%;
}

/* 1:1 — Instagram, avatars, thumbnails */
.square {
aspect-ratio: 1;
width: 100%;
}

/* 3:2 — traditional photography */
.photo {
aspect-ratio: 3 / 2;
width: 100%;
}

/* 21:9 — ultrawide /
.cinematic {
aspect-ratio: 21 / 9;
width: 100%;
}
At width: 800px, the height is calculated:

16 / 9 → 800 × 9 / 16 = 450px
4 / 3 → 800 × 3 / 4 = 600px
1 / 1 → 800 × 1 = 800px
3 / 2 → 800 × 2 / 3 = 533px
21 / 9 → 800 × 9 / 21 = 343px

✅ Width sets the box; aspect-ratio calculates height.
✅ Height adapts as the container shrinks.
✅ Same ratio at every viewport size.

Common ratios:
16:9 → YouTube, video, hero
4:3 → legacy video, product photos
1:1 → Instagram, avatars, thumbnails
3:2 → photography
21:9 → ultrawide cinematics

Choose based on the content, not the device.

✅ With object-fit — images and videos

Crop content to fit the fixed ratio.

media-fit.css
/* Image in a 16:9 box, cropped to fill */
.card-image {
width: 100%;
aspect-ratio: 16 / 9;
object-fit: cover;
border-radius: 8px;
}

/* Image in a 1:1 box, letterboxed (not cropped) */
.avatar {
width: 64px;
aspect-ratio: 1;
object-fit: contain;
background: #f1f5f9;
border-radius: 50%;
}

/* Video element at 16:9 */
.video-player {
width: 100%;
aspect-ratio: 16 / 9;
object-fit: cover;
background: black;
}

/* Iframe (YouTube, Vimeo) at 16:9 /
.embed {
width: 100%;
aspect-ratio: 16 / 9;
border: 0;
}
aspect-ratio alone:
Sets the box shape.
Content may be cropped, stretched, or letterboxed
depending on the browser's default.

object-fit:
cover → crop content to fill the box (no distortion)
contain → letterbox (fit content inside, no crop)
fill → stretch (distorts aspect ratio — rare)
none → show content at native size, centered
scale-down → smaller of none or contain

For images: cover is almost always right —
you want the image to fill the box, even if
it crops edges.

For videos: default is fine (video is already
the right ratio). object-fit: cover is only
needed if the video's intrinsic ratio differs.

For avatars: use contain to avoid cropping faces.

aspect-ratio + object-fit together:
Container maintains the box shape.
Content fills or fits within it.
No padding hacks, no JS.

✅ The old hack vs the new property

Why aspect-ratio replaced the padding-top pattern.

old-vs-new.css
/* ❌ The old padding-top hack (pre-2021) /
.video-wrapper {
position: relative;
width: 100%;
padding-top: 56.25%; / 9/16 = 56.25% for 16:9 */
height: 0;
overflow: hidden;
}

.video-wrapper iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}

/* ✅ The modern aspect-ratio property */
.video-wrapper-modern {
width: 100%;
aspect-ratio: 16 / 9;
}

.video-wrapper-modern iframe {
width: 100%;
height: 100%;
border: 0;
}
The old hack:

❌ Requires a wrapper element.
❌ Requires position: absolute on the child.
❌ padding-top: 56.25% is opaque — no one knows
what 56.25% means without a comment.
❌ Every new ratio needs recalculating:
4:3 → 75%
1:1 → 100%
21:9 → 42.85%
❌ Easy to get wrong.

The modern property:

✅ One line: aspect-ratio: 16 / 9.
✅ No wrapper element needed (though still useful for positioning).
✅ No position: absolute.
✅ Reads as the design intent.
✅ Any ratio expressible as a fraction.
✅ Browser support since 2021 — all modern browsers.

This is one of the clearest examples of
CSS spec catching up to developer workarounds.

Use aspect-ratio. Drop the padding hack.

Don't use aspect-ratio without a width on the element. aspect-ratio sets a preferred ratio, but it needs one dimension to be constrained. A div with no width, no content, and no explicit sizing will be 0×0 — the aspect-ratio does nothing. Set width: 100%, or an explicit width, or place the element in a grid cell with a fixed width. Same for images inside a flex container: if the image is flex-shrunk to 0 width, aspect-ratio can't compute a height. The rule: aspect-ratio needs a width to work against.

⚠️ Common mistakes

The aspect-ratio mistakes that cost real time.

1. No width on the element

aspect-ratio has nothing to work against. Fix: set width: 100% or explicit width.

2. Forgetting object-fit on images

The image is stretched, cropped weirdly, or ignored. Fix: object-fit: cover.

3. Confusing aspect-ratio and object-fit

They solve different problems. Fix: aspect-ratio for the box, object-fit for the content.

4. Setting explicit height overrides aspect-ratio

height: 100vh wins over aspect-ratio. Fix: remove the height.

5. aspect-ratio on flex-shrunk images

Image at width: 0 has no ratio. Fix: min-width: 0 on the flex item, or explicit width.

6. Stretching instead of cropping

object-fit: fill distorts. Fix: cover (crop) or contain (letterbox).

7. Missing width/height HTML attributes on img

Layout shifts on load. Fix: add intrinsic width and height.

8. Old browser support

aspect-ratio doesn't work on IE or older Safari. Fix: accept modern-browser requirement, or keep the padding hack fallback.

❓ Frequently asked

What is the CSS aspect-ratio property?

aspect-ratio is a CSS property that sets a preferred width-to-height ratio for an element. aspect-ratio: 16 / 9 keeps the element at a 16:9 ratio — if width is 320px, height is automatically 180px. It replaces the old padding-top hack and works on any element — images, videos, cards, containers. Supported in all modern browsers since 2021.

What is the difference between aspect-ratio and object-fit?

They solve different problems. aspect-ratio controls the box's dimensions — it makes the container a specific shape. object-fit controls how the content (image, video) fills that box — cover (crop to fill), contain (letterbox), fill (stretch). Use both together: aspect-ratio: 16/9 on the container to fix the box shape, object-fit: cover on the image to crop it into that shape.

How do I make a 16:9 video responsive?

Wrap the video (or iframe) in a container with aspect-ratio: 16 / 9 and width: 100%. Set the video itself to width: 100%; height: 100%; object-fit: cover. The container maintains the ratio, and the video fills it. This replaces the old padding-top: 56.25% hack.

Does aspect-ratio work on all elements?

Yes — aspect-ratio works on any element with a width defined. It works on img, video, iframe, div, section, article, and even flex/grid items. For replaced elements (img, video, iframe), the browser uses the element's intrinsic aspect ratio as a default — but you can override with aspect-ratio. For block elements, aspect-ratio only has an effect when the width is constrained.

Why doesn't aspect-ratio work on my element?

Three common causes. (1) The element has no width — aspect-ratio needs one dimension set to compute the other. (2) The element's content forces a different size — for img and video, the intrinsic size may win unless you set object-fit. (3) A conflicting height property — if you set height: 100vh, that overrides the aspect ratio.

Should I use aspect-ratio for images or the HTML width/height attributes?

Use both. HTML width and height attributes on img tell the browser the intrinsic size — this reserves space in the layout before the image loads, preventing layout shift. aspect-ratio in CSS sets the desired display ratio. The best pattern: img width='800' height='600' with CSS .img { aspect-ratio: 16 / 9; object-fit: cover; width: 100% }.

🔗 Related

← All CSS problems
Problem solved · CSS