CSS Aspect-Ratio Table
| Piece | What it does | Field note |
|---|---|---|
aspect-ratio: 16 / 9 | Reserve the shape | Box keeps the ratio even with only ONE dimension set |
img/video intrinsic | The attribute origin | width/height attributes already do this - CSS ratifies it |
square with 50% radius | The circle recipe | Any element: aspect-ratio: 1 + border-radius: 50% = circle |
Replacement vs non-replaced | Where it applies | Replaced elements: intrinsic wins unless both dims forced |
min/max-size override | Content can win | min-height beats the ratio when content overflows - the escape |
Grid/flex children | Stretch vs ratio | align-items: stretch overrides ratio - set align-self or fixed dim |
object-fit pairing | Crop vs distort | aspect-ratio boxes + object-fit: cover = perfect media frames |
Ratios in grids | Consistent cards | grid rows auto + child aspect-ratio = even cards, no padding hacks |
aspect-ratio reserves the SHAPE with one dimension set: aspect-ratio: 16 / 9 means the browser computes the other side from whichever one you give it - the padding-top-percentage hack, retired. It formalizes what img and video width/height attributes already do (the CLS fix).
Bottom line: replacement elements keep their INTRINSIC ratio unless both dimensions are forced; min/max sizes override the ratio when content overflows (the escape hatch); and align-items: stretch in flex/grid defeats the ratio - set the cross dimension or opt out of stretch.
The honest part: the ratio is a PREFERENCE, not a law - content and sizing constraints can win. The robust media frame is the pairing: aspect-ratio reserves the shape, object-fit: cover fills it with cropping instead of distortion.
How to use
- Reserve media shape: .frame { aspect-ratio: 16 / 9; } on the media wrapper - the box exists before the image loads, no layout shift.
- Circle anything: .avatar { aspect-ratio: 1; border-radius: 50%; } - width: 4rem, height auto, one property pair, any base size.
- Crop into the frame: img { width: 100%; height: 100%; object-fit: cover; } inside the ratio box - fill with cropping, never distortion.
Frequently asked questions
What did people do before aspect-ratio, and why was the old hack shaped that way?
The padding-top percentage hack. Padding PERCENTAGES resolve against the parent's WIDTH - so a padding-top: 56.25% (9/16) creates a box whose height tracks its width: a ratio, built from a quirk. The actual content went position: absolute inside. It worked everywhere for a decade, which is why you will still see it - and why it was hated: magic percentages, absolute-positioned children, no semantic box. aspect-ratio: 16/9 expresses the same intent directly, works on any element, and the width/height attributes on img and video (which feed the browser the intrinsic ratio pre-CSS) are the same idea arriving even earlier in the pipeline.
Why doesn't aspect-ratio always win over the content or intrinsic size?
It is a preference in a cascade of constraints. Replaced elements (img, video) carry their OWN intrinsic ratio - CSS aspect-ratio loses to it unless both dimensions are explicitly set (which removes the intrinsic influence). min-width/min-height and content overflow also override: a box with aspect-ratio: 1 and min-height: 200px grows taller when 300px of content lands inside - the ratio yields to the content minimum. This is not a bug; it is the escape hatch. The discipline: ratio boxes that hold live content need the overflow strategy decided (object-fit for media, overflow: auto or min-height relaxation for text).
Why does my aspect-ratio element stretch flat inside a flex or grid row?
align-items: stretch is the default - and it overrides. In a flex row or grid, children stretch to fill the line's cross size; that stretch sets the cross dimension explicitly, which (per the constraints above) beats the ratio. The fixes: align-self: start (or a non-stretch alignment) on the child, or set BOTH dimensions' inputs (width and the ratio, letting height compute). This is the number-one 'aspect-ratio is broken' report, and the answer is always the same: something else is sizing the cross axis - find the stretch and opt out.
How do aspect-ratio and object-fit: cover form the standard media frame?
Shape reservation plus fill policy. aspect-ratio gives the box its intended shape at any layout width; object-fit: cover scales the media to COVER the box, cropping the overflow instead of letterboxing or distorting. Without the ratio, the frame's shape depends on load timing and source dimensions (shift!). Without cover, a mismatched image either distorts (stretch to fit) or letterboxes (contain). Together: a card grid where every image is 4/3, crops gracefully from any source aspect, and renders with zero layout shift - the entire 'responsive media card' pattern in three declarations, replacing the padding-hack frame plus background-image approach.