CSS Aspect Ratio Box

Maintain a fixed aspect ratio on any element using the aspect-ratio property.

Published May 19, 2026 Beginner 7 min read

A CSS aspect ratio box holds a fixed width to height proportion whatever size it ends up being. Give the element aspect-ratio: 16 / 9 and a width, and the browser works out the height. Give it a height instead and it works out the width. It replaces the padding-top hack that dominated responsive embeds for a decade, where a container was padded to a percentage of its own width and the real content was absolutely positioned on top of it.

The property matters most where the size is fluid. A grid cell that is 240px wide on a laptop and 150px on a phone still holds its shape, so a page of thumbnails keeps its rhythm and nothing reflows when images finish loading. The variants below cover a fluid grid of square cells and the padding based fallback, which is still worth knowing because it is what every older codebase is using.

Three fixed ratios

16 / 9
1 / 1
4 / 3

HTML

<div class="ratio-grid">
  <div class="ratio-box ratio-16-9">16 / 9</div>
  <div class="ratio-box ratio-1-1">1 / 1</div>
  <div class="ratio-box ratio-4-3">4 / 3</div>
</div>

CSS

.ratio-grid {
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
  justify-content: center;
}

.ratio-box {
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #0c0c0d;
  font-size: .8rem;
  font-weight: 600;
}

/* Set a width, the height is calculated from the ratio */
.ratio-16-9 {
  aspect-ratio: 16 / 9;
  width: 160px;
  background: #b8ff57;
}

.ratio-1-1 {
  aspect-ratio: 1 / 1;
  width: 90px;
  background: #c084fc;
}

.ratio-4-3 {
  aspect-ratio: 4 / 3;
  width: 120px;
  background: #38bdf8;
}

Other ways to build it

Fluid grid of square cells

The ratio is most useful when the width is not a number anyone wrote down. Here the grid hands each cell whatever width is left after auto-fill has worked out how many fit, and aspect-ratio: 1 turns that into a height. Resize the window and the cells stay square through every step. The colored blocks below stand in for photographs; put a real <img> inside with object-fit: cover and pictures of any proportion crop to the cell rather than stretching to it.

HTML

<div class="ratio-fluid-grid">
  <div class="ratio-cell"><img src="one.jpg" alt=""></div>
  <div class="ratio-cell"><img src="two.jpg" alt=""></div>
</div>

CSS

.ratio-fluid-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
  gap: .75rem;
}

/* the column width is fluid, so the ratio is what fixes the height */
.ratio-cell {
  aspect-ratio: 1;
  border-radius: 10px;
  overflow: hidden;
}

/* without object-fit the picture stretches to the square
   instead of being cropped to it */
.ratio-cell img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

The padding fallback, and how to feature detect it

Percentage padding resolves against the containing block's width, which is the whole trick: padding-top: 56.25% on an empty box gives it a height of 56.25 percent of its width, and that is 16 to 9. The content then has to be lifted onto that padding with absolute positioning, because the padding itself is empty space. The box below is built this way with no aspect-ratio anywhere, so it demonstrates what a browser without the property would show. In real code, wrap it in @supports not (aspect-ratio: 1 / 1) and let everything else take the shorter path.

16 / 9 with padding-top: 56.25%

HTML

<div class="ratio-pad">
  <div class="ratio-pad-inner">16 / 9 with no aspect-ratio</div>
</div>

CSS

/* percentage padding resolves against width, so 56.25% is 9/16 */
.ratio-pad {
  position: relative;
  width: 100%;
  height: 0;
  padding-top: 56.25%;
  border-radius: 10px;
  overflow: hidden;
}

/* the padding is empty space, so the content has to be lifted onto it */
.ratio-pad-inner {
  position: absolute;
  inset: 0;
}

/* everything modern takes the short path instead */
@supports (aspect-ratio: 1 / 1) {
  .ratio-pad {
    height: auto;
    padding-top: 0;
    aspect-ratio: 16 / 9;
  }

  .ratio-pad-inner {
    position: static;
  }
}

How it works

The aspect-ratio property makes an element maintain a width-to-height ratio automatically. Set a width (fixed, percentage, or auto) and the height adjusts to match the ratio. This replaces the old padding-top hack (padding-top:56.25% for 16:9) with a shorter and readable one-liner.

The value is a ratio, written as two numbers with a slash: 16 / 9, 4 / 3, 1 / 1. A single number is also valid and means that number over one, so aspect-ratio: 2 is the same as 2 / 1. Only one of width and height needs to be set. Set both and the ratio is ignored, because there is nothing left for it to compute.

The ratio applies to the box that box-sizing selects. Under the default content-box, padding and border are added on top of a content area that matches the ratio, so a padded element ends up wider than 16 to 9 overall. Under border-box the ratio describes the outer edge, which is nearly always what a designer means. Most stylesheets set border-box globally, which is why this rarely comes up until it does.

The ratio is a preferred size, not a hard limit. A block element's automatic minimum size stops it shrinking below its content, so a caption two lines longer than expected pushes the box taller and the ratio quietly breaks. overflow: hidden restores it by clipping instead, and min-height: 0 lets the box shrink past its content. Neither is a bug, and the failure mode is a row of cards where one is taller than the rest.

Images bring their own ratio from the file. Setting aspect-ratio on an <img> alongside object-fit: cover overrides that and crops to the box, which is how a mixed set of portrait and landscape photographs is forced into one tidy grid. Without object-fit the picture is stretched to the new proportions instead, and the distortion is obvious on anything with a face in it.

Adding width and height attributes to an <img> in the HTML gives the browser a ratio before the file arrives, which is what reserves the space and stops the page jumping as images load. Modern browsers compute an implicit aspect-ratio from those two attributes, so the attributes and the CSS property solve the same layout shift problem from different ends.

CSS properties used

aspect-ratio
Sets the preferred width to height proportion. Works with one definite dimension, and is ignored when both are set.
object-fit
Controls how a replaced element fills a box whose ratio does not match its own. cover crops, contain letterboxes, the default fill distorts.
box-sizing
Decides whether the ratio describes the content box or the border box. border-box is what makes a padded ratio box come out the size it looks like it should.
overflow
hidden keeps the ratio when content would otherwise force the box taller than the proportion allows.
grid-template-columns
repeat(auto-fill, minmax(120px, 1fr)) gives every cell a fluid width, and the ratio turns that into a height.
padding-top
The older technique. A percentage padding resolves against the element's own width, so 56.25% produces a 16 to 9 box with no ratio property involved.

Browser support

FeatureChromeFirefoxSafariEdge
object-fit32361079
grid575210.116
flexbox21286.112
@supports2822912

Can I Use carries no standalone entry for the aspect-ratio property in the dataset this table is generated from, so it is deliberately not listed above rather than filled in from memory. It shipped across the major engines during 2021 and is safe to rely on for anything but a deliberately deep support baseline. Where that baseline matters, feature detect with @supports (aspect-ratio: 1 / 1) and fall back to the padding technique in the second variant, which works everywhere percentage padding does.

Accessibility notes

A ratio box is a layout tool and it changes nothing about the accessibility tree. The risk it introduces is clipping: a box that keeps its proportion while its content grows will hide the overflow, and text that disappears at a large font size or in a different language is a real failure rather than a cosmetic one. Reserve fixed ratios for images, video, and decorative panels rather than for blocks of copy.

Reserving space is the accessibility win here. A page that jumps as images load costs everyone, and it costs most for anyone using a screen magnifier or a switch device, where a target that moves mid tap becomes a misfire. Setting the ratio in CSS, or width and height attributes on the image, keeps the layout still.

Where a ratio box carries a caption, put the caption outside the box rather than inside it. Inside, it competes with the image for a fixed height and it is the first thing clipped when the text wraps to an extra line.

What you can build with it

  • Video embeds. A 16 to 9 wrapper around an <iframe> so a fluid width player keeps its shape without the old absolute positioning dance.
  • Image grids. Square cells holding photographs of every proportion, cropped with object-fit: cover. The CSS lightbox uses exactly this for its thumbnails.
  • Card media areas. The picture at the top of a card holds a 3 to 2 ratio so a row of cards lines up regardless of what each image measures.
  • Avatars and logos. aspect-ratio: 1 with a border radius, which stays circular instead of turning into an ellipse when the container is narrow.
  • Chart and map containers. A plot area that keeps its proportions as the page resizes, so the drawing inside it does not need to be recalculated on every breakpoint.

Mistakes worth avoiding

  • Setting both width and height. The two definite sizes win and the ratio is ignored, with no warning anywhere.
  • Leaving box-sizing at content-box on a padded ratio box. Padding is added outside the ratio, so the visible box is wider than the proportion asked for.
  • Assuming the ratio is a hard constraint. Content taller than the box pushes it taller, which is why one card in a row ends up out of line with the rest.
  • Using aspect-ratio on an image without object-fit. The picture stretches to the new proportions rather than cropping to them.
  • Applying a ratio to a stretched flex item. The item already has a definite cross size from align-items: stretch, and that size wins.

Frequently asked questions

How do you set an aspect ratio in CSS?
Write aspect-ratio: 16 / 9 and give the element one definite dimension, usually a width. The browser derives the other one. A single number works too, so aspect-ratio: 1 is a square.
Why is my aspect-ratio being ignored?
Almost always because both width and height are set, which leaves nothing for the ratio to compute. The other common cause is content taller than the ratio allows, since the property sets a preferred size rather than a maximum. Add overflow: hidden to keep the shape.
What is the padding-top trick and do I still need it?
Percentage padding resolves against the containing block's width, so padding-top: 56.25% on an empty box produces a height that is 56.25 percent of its width, which is 16 to 9. It still works, and it is what you fall back to inside @supports not (aspect-ratio: 1 / 1) when a very old browser matters.
Does aspect-ratio work on images?
Yes, and it overrides the image's own proportions. Pair it with object-fit: cover so the picture is cropped to the box rather than stretched, which is how a set of mixed portrait and landscape photographs is made to fit one grid.
Can aspect ratio boxes stop layout shift?
That is the main reason to use them. Reserving the space before the image arrives means nothing below it moves when it loads. width and height attributes on the <img> do the same job, because browsers derive an implicit ratio from them.