# The CSS aspect-ratio property and the math behind it

> Learn how the CSS aspect-ratio property replaces the padding-top hack, the math behind contain and cover, and how width and height attributes prevent CLS.

Author: [Flavio Copes](https://flaviocopes.com/about/) | Published: 2026-08-04 | Topics: [CSS](https://flaviocopes.com/tags/css/) | Canonical: https://flaviocopes.com/css-aspect-ratio-property/

An aspect ratio is the relationship between width and height. A 1920×1080 video is 16:9. A square is 1:1.

For years, keeping an element at a fixed ratio while its width changed required a hack. Now CSS has a property for it. Let's look at both, and at the math behind ratio calculations, because it comes up more often than you'd think.

## The old way: the padding-top hack

Percentage padding on an element is calculated from the **width** of its parent. Even `padding-top`.

That quirk was the basis of the classic trick. You give a box zero height and a percentage top padding, and the padding *becomes* the height:

```css
.box {
  position: relative;
  width: 100%;
  padding-top: 56.25%;
}
.box > * {
  position: absolute;
  inset: 0;
}
```

Where does 56.25 come from? It's the ratio math:

```
height / width × 100 = 9 / 16 × 100 = 56.25%
```

The content then has to be absolutely positioned inside, because the box itself has no real height to flow into.

I used this exact technique in [responsive YouTube video embeds](https://flaviocopes.com/responsive-youtube-videos/). It works, but it's indirect, it needs a wrapper element, and nobody remembers the formula.

## The modern way: aspect-ratio

Now you write what you mean:

```css
.box {
  aspect-ratio: 16 / 9;
}
```

Set a width (or let the layout set one), and the browser computes the height. Set a height instead, and it computes the width. No wrapper, no absolute positioning, no percentage tricks.

It works for any ratio:

```css
aspect-ratio: 1;        /* square */
aspect-ratio: 4 / 3;    /* old TV */
aspect-ratio: 2.39 / 1; /* cinemascope */
```

One important detail: `aspect-ratio` sets a *preferred* ratio, not a forced one. If you set both `width` and `height` explicitly, or if the content is taller than the computed height, the ratio gives way. That's usually what you want — text won't overflow a box just to preserve a ratio. If you truly need to force it, add `overflow: hidden` or set `min-height: 0`.

I wrote about the video embed use case specifically in [how to embed YouTube videos using the correct aspect ratio](https://flaviocopes.com/how-to-embed-youtube-videos-correct-aspect-ratio/).

## The ratio math

Behind every ratio calculation there's one relationship:

```
width / height = ratio
```

From it you derive everything:

```
height = width / ratio
width = height × ratio
```

So a 16:9 element that's 800px wide is 800 / (16/9) = 450px tall.

To reduce dimensions to their simplest ratio, divide both by their greatest common divisor. For 1920×1080, the GCD is 120, so you get 16:9. That's how you find out that 1280×720 and 1920×1080 are the same shape.

I put all of this into an [aspect ratio calculator](https://flaviocopes.com/tools/aspect-ratio/): it reduces any dimensions to the simplest ratio, solves the missing dimension when you lock one side, and computes the fit calculations we're about to cover.

## Contain and cover math

Things get more interesting when a source (an image, a video) has one ratio and the box it goes into has another. There are two ways to fit it, and they're exactly what `object-fit: contain` and `object-fit: cover` do.

**Contain**: scale the source until it fully fits inside the box. Compare the two ratios first:

- if the source is *wider* than the box, the width is the constraint: rendered width = box width, rendered height = box width / source ratio
- if the source is *taller*, the height is the constraint: rendered height = box height, rendered width = box height × source ratio

The leftover space is the **letterbox** — the black bars you see when a widescreen movie plays on a squarer screen. The bar size is just the difference, split in two:

```
letterbox = (box height − rendered height) / 2
```

**Cover** flips the logic: scale the source until it fills the box completely, and whatever sticks out gets cropped. Same comparison, opposite branches. If the source is wider than the box, now the *height* matches the box, the width overflows, and:

```
crop per side = (rendered width − box width) / 2
```

A concrete example. A 1920×1080 video (ratio 1.78) in a 400×300 box (ratio 1.33):

- **contain**: width is the constraint. Rendered at 400×225, with a 37.5px letterbox bar on top and bottom.
- **cover**: height is the constraint. Rendered at 533×300, cropping about 67px off each side.

This math is worth knowing even if `object-fit` handles it for you, because it answers real questions: "how much of my hero image gets cropped on this screen?" is a cover calculation.

## width, height attributes and CLS

There's a performance angle to aspect ratios too.

When a browser loads a page, images arrive after the HTML. If the browser doesn't know how tall an image will be, it lays out the text first, then shoves everything down when the image arrives. That jump is **layout shift**, and Google measures it as CLS (Cumulative Layout Shift) in its Core Web Vitals.

The fix: always set the `width` and `height` attributes on images.

```html
<img src="/images/dog.jpg" width="1600" height="900" alt="my dog">
```

These attributes don't fix the displayed size — your CSS still controls that, typically `width: 100%; height: auto`. What they do is give the browser the *ratio*. Modern browsers internally derive `aspect-ratio: 1600 / 900` from those attributes and reserve the correct space before the image loads.

So the modern setup is: attributes in the HTML for the ratio, CSS for the responsive sizing. No layout shift, no wrapper hacks.

My advice: reach for the `aspect-ratio` property for boxes, embeds and placeholders, and keep the padding hack in your back pocket only for the rare old browser you still have to support. Everything current understands the property.
