Two properties solve most picture sizing problems. aspect-ratio: 16 / 9 makes a box keep that shape at any width, replacing the old padding-top hack. object-fit decides how an img or video fills that box: cover crops, contain letterboxes, fill stretches. object-position picks which part stays visible when cover crops.
| Goal | CSS | Tailwind |
|---|---|---|
| Square box | aspect-ratio: 1 | aspect-square |
| Video shape | aspect-ratio: 16 / 9 | aspect-video |
| Any ratio | aspect-ratio: 4 / 3 | aspect-4/3 or aspect-[4/3] |
| Fill and crop | object-fit: cover | object-cover |
| Show it all | object-fit: contain | object-contain |
| Keep the top | object-position: top | object-top |
Updated
Below, one test picture sits in a box you can reshape. Switch between the five object-fit values, click the picture to move the focal point, and copy the CSS or Tailwind classes. Further down: the padding hack next to aspect-ratio, responsive video embeds and card grids with even thumbnails.
| Value | Tailwind |
|---|---|
| fill | object-fill |
| contain | object-contain |
| cover | object-cover |
| none | object-none |
| scale-down | object-scale-down |
Before aspect-ratio, a box got its shape from padding-top as a percentage, because vertical padding percentages are measured against the width. It works, but the content has to be absolutely positioned inside. Both boxes below are 16:9.
56.25% is 9 divided by 16. The modern version needs one line and lets content flow normally.
<style>
.old { position: relative; padding-top: 56.25%; background: #fde68a }
.old > div { position: absolute; inset: 0; display: grid; place-items: center }
.new { aspect-ratio: 16 / 9; background: #bfdbfe; display: grid; place-items: center }
.wrap { display: grid; grid-template-columns: 1fr 1fr; gap: 10px }
</style>
<div class="wrap">
<div class="old"><div>padding-top: 56.25%</div></div>
<div class="new">aspect-ratio: 16 / 9</div>
</div>The picture is 3:2 and every box is square, so each value has a mismatch to deal with and the differences show clearly.
| Value | What happens | Tailwind |
|---|---|---|
| fill | Stretches the image to the box. The default for img and video. Distorts when the ratios differ. | object-fill |
| contain | Scales the whole image to fit inside the box. Leaves empty bands (letterboxing) when the ratios differ. | object-contain |
| cover | Scales the image to fill the box and crops the overflow. No distortion, no bands, some of the picture is cut. | object-cover |
| none | Keeps the image at its natural size and crops whatever does not fit. Good for showing a detail at 1:1. | object-none |
| scale-down | Acts like none or contain, whichever gives the smaller result. Never enlarges a small image. | object-scale-down |
The same 300 by 200 picture in five 110 pixel squares. Watch the red dot: it is the subject cover must not lose.
<style>
.row { display: flex; flex-wrap: wrap; gap: 8px; font: 12px system-ui }
.row img { width: 110px; height: 110px; background: #f1f5f9; outline: 1px solid #94a3b8 }
</style>
<div class="row">
<figure><img src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22300%22%20height%3D%22200%22%20viewBox%3D%220%200%20300%20200%22%20preserveAspectRatio%3D%22none%22%3E%3Crect%20width%3D%22300%22%20height%3D%22200%22%20fill%3D%22%23bfdbfe%22%2F%3E%3Ccircle%20cx%3D%22250%22%20cy%3D%2245%22%20r%3D%2222%22%20fill%3D%22%23fbbf24%22%2F%3E%3Cpath%20d%3D%22M0%20150%20Q70%2095%20150%20140%20T300%20125%20V200%20H0Z%22%20fill%3D%22%2322c55e%22%2F%3E%3Cpath%20d%3D%22M0%20175%20Q90%20140%20190%20172%20T300%20165%20V200%20H0Z%22%20fill%3D%22%2315803d%22%2F%3E%3Ccircle%20cx%3D%2285%22%20cy%3D%22128%22%20r%3D%2216%22%20fill%3D%22%23dc2626%22%2F%3E%3Crect%20x%3D%222%22%20y%3D%222%22%20width%3D%22296%22%20height%3D%22196%22%20fill%3D%22none%22%20stroke%3D%22%231e3a8a%22%20stroke-width%3D%224%22%2F%3E%3C%2Fsvg%3E" alt="Test landscape" width="300" height="200" style="object-fit: fill"><figcaption>fill</figcaption></figure>
<figure><img src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22300%22%20height%3D%22200%22%20viewBox%3D%220%200%20300%20200%22%20preserveAspectRatio%3D%22none%22%3E%3Crect%20width%3D%22300%22%20height%3D%22200%22%20fill%3D%22%23bfdbfe%22%2F%3E%3Ccircle%20cx%3D%22250%22%20cy%3D%2245%22%20r%3D%2222%22%20fill%3D%22%23fbbf24%22%2F%3E%3Cpath%20d%3D%22M0%20150%20Q70%2095%20150%20140%20T300%20125%20V200%20H0Z%22%20fill%3D%22%2322c55e%22%2F%3E%3Cpath%20d%3D%22M0%20175%20Q90%20140%20190%20172%20T300%20165%20V200%20H0Z%22%20fill%3D%22%2315803d%22%2F%3E%3Ccircle%20cx%3D%2285%22%20cy%3D%22128%22%20r%3D%2216%22%20fill%3D%22%23dc2626%22%2F%3E%3Crect%20x%3D%222%22%20y%3D%222%22%20width%3D%22296%22%20height%3D%22196%22%20fill%3D%22none%22%20stroke%3D%22%231e3a8a%22%20stroke-width%3D%224%22%2F%3E%3C%2Fsvg%3E" alt="Test landscape" width="300" height="200" style="object-fit: contain"><figcaption>contain</figcaption></figure>
<figure><img src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22300%22%20height%3D%22200%22%20viewBox%3D%220%200%20300%20200%22%20preserveAspectRatio%3D%22none%22%3E%3Crect%20width%3D%22300%22%20height%3D%22200%22%20fill%3D%22%23bfdbfe%22%2F%3E%3Ccircle%20cx%3D%22250%22%20cy%3D%2245%22%20r%3D%2222%22%20fill%3D%22%23fbbf24%22%2F%3E%3Cpath%20d%3D%22M0%20150%20Q70%2095%20150%20140%20T300%20125%20V200%20H0Z%22%20fill%3D%22%2322c55e%22%2F%3E%3Cpath%20d%3D%22M0%20175%20Q90%20140%20190%20172%20T300%20165%20V200%20H0Z%22%20fill%3D%22%2315803d%22%2F%3E%3Ccircle%20cx%3D%2285%22%20cy%3D%22128%22%20r%3D%2216%22%20fill%3D%22%23dc2626%22%2F%3E%3Crect%20x%3D%222%22%20y%3D%222%22%20width%3D%22296%22%20height%3D%22196%22%20fill%3D%22none%22%20stroke%3D%22%231e3a8a%22%20stroke-width%3D%224%22%2F%3E%3C%2Fsvg%3E" alt="Test landscape" width="300" height="200" style="object-fit: cover"><figcaption>cover</figcaption></figure>
<figure><img src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22300%22%20height%3D%22200%22%20viewBox%3D%220%200%20300%20200%22%20preserveAspectRatio%3D%22none%22%3E%3Crect%20width%3D%22300%22%20height%3D%22200%22%20fill%3D%22%23bfdbfe%22%2F%3E%3Ccircle%20cx%3D%22250%22%20cy%3D%2245%22%20r%3D%2222%22%20fill%3D%22%23fbbf24%22%2F%3E%3Cpath%20d%3D%22M0%20150%20Q70%2095%20150%20140%20T300%20125%20V200%20H0Z%22%20fill%3D%22%2322c55e%22%2F%3E%3Cpath%20d%3D%22M0%20175%20Q90%20140%20190%20172%20T300%20165%20V200%20H0Z%22%20fill%3D%22%2315803d%22%2F%3E%3Ccircle%20cx%3D%2285%22%20cy%3D%22128%22%20r%3D%2216%22%20fill%3D%22%23dc2626%22%2F%3E%3Crect%20x%3D%222%22%20y%3D%222%22%20width%3D%22296%22%20height%3D%22196%22%20fill%3D%22none%22%20stroke%3D%22%231e3a8a%22%20stroke-width%3D%224%22%2F%3E%3C%2Fsvg%3E" alt="Test landscape" width="300" height="200" style="object-fit: none"><figcaption>none</figcaption></figure>
<figure><img src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22300%22%20height%3D%22200%22%20viewBox%3D%220%200%20300%20200%22%20preserveAspectRatio%3D%22none%22%3E%3Crect%20width%3D%22300%22%20height%3D%22200%22%20fill%3D%22%23bfdbfe%22%2F%3E%3Ccircle%20cx%3D%22250%22%20cy%3D%2245%22%20r%3D%2222%22%20fill%3D%22%23fbbf24%22%2F%3E%3Cpath%20d%3D%22M0%20150%20Q70%2095%20150%20140%20T300%20125%20V200%20H0Z%22%20fill%3D%22%2322c55e%22%2F%3E%3Cpath%20d%3D%22M0%20175%20Q90%20140%20190%20172%20T300%20165%20V200%20H0Z%22%20fill%3D%22%2315803d%22%2F%3E%3Ccircle%20cx%3D%2285%22%20cy%3D%22128%22%20r%3D%2216%22%20fill%3D%22%23dc2626%22%2F%3E%3Crect%20x%3D%222%22%20y%3D%222%22%20width%3D%22296%22%20height%3D%22196%22%20fill%3D%22none%22%20stroke%3D%22%231e3a8a%22%20stroke-width%3D%224%22%2F%3E%3C%2Fsvg%3E" alt="Test landscape" width="300" height="200" style="object-fit: scale-down"><figcaption>scale-down</figcaption></figure>
</div>Give the iframe width 100% and an aspect-ratio. No wrapper div and no absolute positioning needed.
<iframe
src="https://www.youtube-nocookie.com/embed/VIDEO_ID"
title="Product walkthrough"
style="width: 100%; aspect-ratio: 16 / 9; border: 0"
loading="lazy"
allow="accelerometer; encrypted-media; picture-in-picture"
allowfullscreen></iframe>
<!-- A native video can crop to a vertical shape too -->
<video src="/clip.mp4" style="width: 100%; aspect-ratio: 9 / 16; object-fit: cover" muted playsinline controls></video>Uploads come in all shapes. aspect-ratio plus object-fit: cover makes the grid tidy without editing a single file.
<style>
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 10px; font: 13px system-ui }
.card { border: 1px solid #e2e8f0; border-radius: 10px; overflow: hidden }
.card img { display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover; object-position: 28% 64% }
.card p { margin: 6px 8px }
</style>
<div class="grid">
<div class="card"><img src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22300%22%20height%3D%22200%22%20viewBox%3D%220%200%20300%20200%22%20preserveAspectRatio%3D%22none%22%3E%3Crect%20width%3D%22300%22%20height%3D%22200%22%20fill%3D%22%23bfdbfe%22%2F%3E%3Ccircle%20cx%3D%22250%22%20cy%3D%2245%22%20r%3D%2222%22%20fill%3D%22%23fbbf24%22%2F%3E%3Cpath%20d%3D%22M0%20150%20Q70%2095%20150%20140%20T300%20125%20V200%20H0Z%22%20fill%3D%22%2322c55e%22%2F%3E%3Cpath%20d%3D%22M0%20175%20Q90%20140%20190%20172%20T300%20165%20V200%20H0Z%22%20fill%3D%22%2315803d%22%2F%3E%3Ccircle%20cx%3D%2285%22%20cy%3D%22128%22%20r%3D%2216%22%20fill%3D%22%23dc2626%22%2F%3E%3Crect%20x%3D%222%22%20y%3D%222%22%20width%3D%22296%22%20height%3D%22196%22%20fill%3D%22none%22%20stroke%3D%22%231e3a8a%22%20stroke-width%3D%224%22%2F%3E%3C%2Fsvg%3E" alt="Test landscape" width="300" height="200"><p>Hill walk</p></div>
<div class="card"><img src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22300%22%20height%3D%22200%22%20viewBox%3D%220%200%20300%20200%22%20preserveAspectRatio%3D%22none%22%3E%3Crect%20width%3D%22300%22%20height%3D%22200%22%20fill%3D%22%23bfdbfe%22%2F%3E%3Ccircle%20cx%3D%22250%22%20cy%3D%2245%22%20r%3D%2222%22%20fill%3D%22%23fbbf24%22%2F%3E%3Cpath%20d%3D%22M0%20150%20Q70%2095%20150%20140%20T300%20125%20V200%20H0Z%22%20fill%3D%22%2322c55e%22%2F%3E%3Cpath%20d%3D%22M0%20175%20Q90%20140%20190%20172%20T300%20165%20V200%20H0Z%22%20fill%3D%22%2315803d%22%2F%3E%3Ccircle%20cx%3D%2285%22%20cy%3D%22128%22%20r%3D%2216%22%20fill%3D%22%23dc2626%22%2F%3E%3Crect%20x%3D%222%22%20y%3D%222%22%20width%3D%22296%22%20height%3D%22196%22%20fill%3D%22none%22%20stroke%3D%22%231e3a8a%22%20stroke-width%3D%224%22%2F%3E%3C%2Fsvg%3E" alt="Test landscape" width="300" height="200"><p>Lake loop</p></div>
<div class="card"><img src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22300%22%20height%3D%22200%22%20viewBox%3D%220%200%20300%20200%22%20preserveAspectRatio%3D%22none%22%3E%3Crect%20width%3D%22300%22%20height%3D%22200%22%20fill%3D%22%23bfdbfe%22%2F%3E%3Ccircle%20cx%3D%22250%22%20cy%3D%2245%22%20r%3D%2222%22%20fill%3D%22%23fbbf24%22%2F%3E%3Cpath%20d%3D%22M0%20150%20Q70%2095%20150%20140%20T300%20125%20V200%20H0Z%22%20fill%3D%22%2322c55e%22%2F%3E%3Cpath%20d%3D%22M0%20175%20Q90%20140%20190%20172%20T300%20165%20V200%20H0Z%22%20fill%3D%22%2315803d%22%2F%3E%3Ccircle%20cx%3D%2285%22%20cy%3D%22128%22%20r%3D%2216%22%20fill%3D%22%23dc2626%22%2F%3E%3Crect%20x%3D%222%22%20y%3D%222%22%20width%3D%22296%22%20height%3D%22196%22%20fill%3D%22none%22%20stroke%3D%22%231e3a8a%22%20stroke-width%3D%224%22%2F%3E%3C%2Fsvg%3E" alt="Test landscape" width="300" height="200"><p>Ridge path</p></div>
</div>| CSS | Tailwind |
|---|---|
| aspect-ratio: 1 / 1 | aspect-square |
| aspect-ratio: 16 / 9 | aspect-video |
| aspect-ratio: auto | aspect-auto |
| aspect-ratio: 3 / 2 | aspect-3/2 (v4) or aspect-[3/2] |
| object-fit: cover / contain / fill | object-cover / object-contain / object-fill |
| object-fit: none / scale-down | object-none / object-scale-down |
| object-position: center / top / bottom | object-center / object-top / object-bottom |
| object-position: 30% 40% | object-[30%_40%] |
The ratio only kicks in when one dimension is automatic. Set a width and leave height as auto, and the browser computes the height from the ratio. Set both width and height and the ratio is ignored, since there is nothing left to work out.
The value auto 3 / 2 means use the element's natural ratio when it has one, such as a loaded image, and fall back to 3 / 2 before it loads or when it has none. That is exactly how width and height attributes on img behave behind the scenes.
object-position takes the same values as background-position: keywords like top or right, percentages, or lengths. 50% 50% is the default and keeps the centre. A percentage lines up that point of the image with the same point of the box, so 30% 40% keeps the area a third in from the left and a little above the middle.
For a content system, store the focal point per image as two percentages and write it into an inline style. Every crop on the site then keeps the subject in frame, whatever ratio the layout uses.
aspect-ratio shapes the box itself, for any element. object-fit only applies to replaced content such as img, video and canvas, and decides how that content is drawn inside its box. You usually use both: aspect-ratio on the image to fix its shape, object-fit: cover so the picture fills it.
The image box has the same ratio as the picture, so there is nothing to crop or stretch. object-fit only shows a difference once the box has a different shape, for example a fixed height plus width: 100%, or an aspect-ratio that differs from the file.
Not for current browsers. aspect-ratio has worked in Chrome, Edge, Firefox and Safari since 2021. Keep the hack only if you must support older browsers, and check caniuse for your audience.
No. For CSS backgrounds the equivalents are background-size: cover or contain, and background-position for the focal point. object-fit is for real img and video elements, which are better for content images because they carry alt text and support srcset.
Yes. Any element can take it. A div with width: 100% and aspect-ratio: 1 becomes a square that grows with its column, which is handy for map placeholders, avatars and skeleton loaders.
Related: Aspect ratio calculator, HTML images guide, HTML iframe and video, Flexbox and grid cheat sheet, CSS sizing functions.
Start for free or see all free tools. We.Inc is free to start, with no card needed. AI building is on paid plans from $20 a month.
We.Inc is an AI-powered website builder you can resell under your own brand. Launch a branded client dashboard, bill on Stripe Connect, and deliver AI-generated websites in minutes. White-label plans start at $99 a month for 25 client sites, with a 7-day free trial and no per-site fees.