Suggest an editImprove this articleRefine the answer for “CSS aspect-ratio”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**`aspect-ratio`** is a CSS property that locks an element's width-to-height ratio. The browser computes the missing dimension automatically. ```css .video { width: 100%; aspect-ratio: 16 / 9; /* height = width * (9/16). At 800px width: 450px height. */ } ``` **Key rule:** set only one dimension. If both `width` and `height` are explicit, the ratio is ignored.Shown above the full answer for quick recall.Answer (EN)Image**`aspect-ratio`** is a CSS property that automatically computes an element's height from its width (or vice versa) using a fixed ratio. ## Theory ### TL;DR - Like a photo frame that adjusts its height to match any width without distortion. You set the ratio, the browser does the math. - Before 2021: developers used `padding-bottom: 56.25%` hacks on wrapper divs. One property replaces all of that now. - Set one dimension (width or height) plus `aspect-ratio`, and the browser solves for the other. - Skip it when both dimensions are already set explicitly. ### Quick example ```css .video { width: 100%; max-width: 800px; aspect-ratio: 16 / 9; background: #000; } /* At 800px width: height is 450px. At 400px: height is 225px. */ ``` One property. No JavaScript. No padding tricks. The container stays 16:9 at any viewport size. ### Why this replaced the padding hack Before Chrome 88 (January 2021), percentage `height` had no reference point unless the parent had an explicit height. So developers used `padding-bottom: 56.25%` on a wrapper, because percentage padding always computes from width. A div with `height: 0; padding-bottom: 56.25%` gave you a 16:9 box, and the actual content sat inside via `position: absolute`. It worked. But it was a hack. Extra markup, non-obvious CSS, confusing for anyone reading it later. In practice, I still see this pattern in codebases that started before 2021, often copy-pasted without anyone knowing a native solution exists. `aspect-ratio` solves this directly. The browser computes `used-height = used-width * (ratio-height / ratio-width)` during the layout pass, after width is known. No wrappers. No padding tricks. ### When to use - Responsive video containers: `width: 100%` + `aspect-ratio: 16 / 9` - Image gallery thumbnails that scale with grid column width - Product cards where the image area must keep its shape during resize - Placeholder boxes before images load Skip it when both `width` and `height` are set explicitly. The property is ignored in that case. Also skip it if Flexbox or Grid already controls the shape you want. ### How the browser resolves it Browsers (Blink, WebKit, Gecko) process `aspect-ratio` during the layout pass, after width is determined. For a block element with `width: 100%`, width is known first and height is computed from the ratio. In a vertical flex container where height is constrained, it works the opposite way. If both dimensions are explicit, the ratio is ignored entirely. One edge case worth knowing: `min-height` and `max-height` can override the ratio-computed value. If the computed height from the ratio falls below `min-height`, the browser uses `min-height` and the ratio stops working as expected. ### Common mistakes **Setting `height` alongside `aspect-ratio` in Flexbox:** ```css /* Wrong - height overrides the ratio */ .flex-item { flex: 1; aspect-ratio: 16 / 9; height: 100%; } /* Correct - remove height, let ratio set it */ .flex-item { flex: 1; aspect-ratio: 16 / 9; } ``` **Assuming `aspect-ratio: auto` preserves image intrinsic ratio on all elements:** For replaced elements like `img` or `video`, `auto` does use the file's intrinsic ratio. But for regular `div` elements, `auto` defaults to 1:1. For images, `width: 100%; height: auto;` is usually the simpler and more predictable path. **Using it on table cells:** Table layout ignores `aspect-ratio`. The table sizing algorithm overrides it. Wrap the cell content in a `div` and apply the ratio there instead. **Parent collapses to zero in a float context:** If the parent has no height reference, the ratio cannot compute. Use Flexbox or Grid as the container layout, or give the parent an explicit height. ### Real-world usage - **Tailwind CSS:** `aspect-[16/9]` utility in v3+ - **Bootstrap 5.3+:** `.ratio` class uses `aspect-ratio` with a `@supports` fallback for older browsers - **Next.js / Vercel templates:** video thumbnails and hero image containers - **react-player library:** wraps iframes with `aspectRatio` in inline styles instead of the old padding approach - Legacy browsers: `@supports not (aspect-ratio: 1) { padding-bottom: 56.25%; }` for Safari before v15 ### Follow-up questions **Q:** What happens if both `width` and `height` are set alongside `aspect-ratio`? **A:** The ratio is ignored. Explicit dimensions always win. `aspect-ratio` only fills in the missing one. **Q:** How does `aspect-ratio: auto` work on images? **A:** For replaced elements (img, video), `auto` uses the file's intrinsic ratio. For regular elements it defaults to 1:1. For images, `width: 100%; height: auto;` is usually what you actually want. **Q:** How do you support browsers before Chrome 88? **A:** Use `@supports not (aspect-ratio: 1)` and provide the `padding-bottom` hack as a fallback. No separate polyfill needed, just progressive enhancement. **Q:** In a CSS Grid, why does `aspect-ratio` sometimes get ignored on grid items? **A:** Grid computes track sizes first. If a row track has an explicit height or the grid stretches items to fill the row, that height wins over the ratio. Fix: set `align-items: start` on the grid container, or apply the ratio to an inner div inside the grid item. **Q:** Can you use CSS custom properties with `aspect-ratio`? **A:** Yes. `aspect-ratio: var(--ratio)` works fine. Define `--ratio: 16 / 9` in `:root` and reuse across components. ## Examples ### Responsive video embed The classic use case. An iframe that stays 16:9 on any screen width, with no padding hack and no JavaScript. ```html <div class="video-wrapper"> <iframe src="https://www.youtube.com/embed/dQw4w9WgXcQ" style="width: 100%; height: 100%; border: none;" allowfullscreen> </iframe> </div> ``` ```css .video-wrapper { width: 100%; max-width: 800px; aspect-ratio: 16 / 9; margin: 0 auto; overflow: hidden; /* No position: absolute. No padding-bottom. Just works. */ } ``` At 800px the height is 450px. At 400px it is 225px. The iframe fills the wrapper because its own width and height are 100% of the parent, and the parent's height comes entirely from the ratio. ### Product image grid with consistent thumbnails E-commerce listings need square thumbnails regardless of the original image dimensions. `aspect-ratio` locks the shape, `object-fit` handles the crop. ```css .product-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 1rem; } .product-image { width: 100%; aspect-ratio: 1 / 1; /* always square */ overflow: hidden; background: #f5f5f5; border-radius: 4px; } .product-image img { width: 100%; height: 100%; object-fit: cover; /* crop, not squish */ } ``` `object-fit: cover` crops the image to fill the square without distortion. `aspect-ratio: 1 / 1` guarantees the box stays square regardless of how wide the grid column gets.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.