TL;DR: To maintain aspect ratio in CSS, use the native aspect-ratio
property on boxes, images, and iframes. Pair images with HTML width
/height
to reserve space (prevent CLS), and use object-fit
for cropping or containment. Add the classic padding-box fallback only for very old browsers.
What “maintain aspect ratio” means & why it matters
An aspect ratio is the width-to-height relationship of an element (e.g., 16/9
, 4/3
, 1/1
). Preserving it prevents distortion, avoids layout shifts as media loads, and keeps responsive UIs consistent across devices—contributing to better UX and Core Web Vitals.
The modern solution: aspect-ratio
aspect-ratio
gives the browser a preferred width:height ratio. It applies when at least one dimension is auto
. If both width and height are fixed, the ratio won’t change the box.
/* Squares, rectangles, 16:9 frames */
.square { aspect-ratio: 1 / 1; }
.golden { aspect-ratio: 1.618 / 1; }
.video-frame { aspect-ratio: 16 / 9; width: 100%; }
- Quick rule: set
width
(often100%
) and let the browser calculateheight
from your ratio. - Replaced elements: images/videos/iframes have intrinsic sizes; the intrinsic ratio wins unless you provide different sizing rules. You can still use
aspect-ratio
to reserve space.
Images: intrinsic size, object-fit
, and zero jank
For images, combine three best practices:
- Reserve space by setting HTML
width
andheight
attributes that reflect the source image’s intrinsic dimensions (the browser derives the ratio from these values). - Optionally, add a CSS
aspect-ratio
as an extra safeguard before the image loads. - Use
object-fit
to control cropping (cover
) or containment (contain
), andobject-position
for the focal point.
<img
class="thumb"
src="/images/cat.jpg"
alt="Cat on a windowsill"
width="1200" height="800">
.thumb {
width: 100%;
height: auto; /* uses the intrinsic ratio from width/height attrs */
aspect-ratio: 3 / 2; /* optional placeholder ratio */
object-fit: cover; /* or 'contain' if you never want cropping */
object-position: 50% 50%;
}
Bonus: Add responsive sources with srcset
/sizes
to serve the right image per viewport.
Responsive video & iframes (YouTube, Vimeo, maps)
The native property makes embeds painless—no wrappers or magic numbers.
<iframe class="yt" src="https://www.youtube.com/embed/VIDEO_ID" title="Video" allowfullscreen></iframe>
.yt {
width: 100%;
aspect-ratio: 16 / 9;
border: 0;
}
For vertically oriented content (e.g., shorts), switch to 9/16
.
Cards & grids that always line up
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
gap: 1rem;
}
.card {
aspect-ratio: 4 / 3; /* consistent tile heights */
display: grid;
place-items: center;
padding: 1rem;
border-radius: 0.75rem;
}
Because each card has a set ratio, the grid remains tidy at any viewport size.
Advanced notes & edge cases
- When ratio seems ignored: If you set both
width
andheight
to fixed values, the browser won’t useaspect-ratio
. Leave one dimension asauto
. - Viewport-based layouts: You can adapt UI by viewport ratio, e.g., show a sidebar only on wide screens.
/* Media queries using aspect ratio */
@media (min-aspect-ratio: 3/2) {
.sidebar { display: block; }
}
/* Range syntax is supported in many modern browsers */
@media (aspect-ratio > 3 / 2) {
.sidebar { display: block; }
}
Legacy fallback: the padding-box technique
For very old browsers, use a percentage padding to simulate height (percentage is based on the element’s width). Prefer the native property today.
<div class="ratio-16x9">
<div class="ratio-content">...content/iframe...</div>
</div>
.ratio-16x9 { position: relative; padding-top: 56.25%; } /* 9/16 */
.ratio-content { position: absolute; inset: 0; }
Common mistakes (and quick fixes)
- Both dimensions fixed. Fix: keep either width or height as
auto
. - Unwanted cropping. Fix: use
object-fit: contain
or set a different focal point withobject-position
. - Layout shift on image load. Fix: set HTML
width
/height
to expose intrinsic ratio (and includeloading="lazy"
judiciously). - Overusing wrappers and hacks. Fix: use native
aspect-ratio
first; add the padding-box fallback only if necessary.
Copy-paste snippets
Square avatars (center-cropped)
.avatar { aspect-ratio: 1 / 1; width: 96px; border-radius: 50%; object-fit: cover; }
Responsive video/iframe
iframe, video { width: 100%; aspect-ratio: 16 / 9; }
Product image tiles (no cropping)
.product-img { aspect-ratio: 4 / 3; width: 100%; object-fit: contain; background: #f7f7f8; }
Responsive squares in a CSS Grid
.square-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: .75rem; }
.square-grid > * { aspect-ratio: 1 / 1; }
FAQ: CSS & aspect ratios
How do I maintain aspect ratio in CSS?
Use aspect-ratio
(e.g., 16/9
) with one dimension left auto
. For media, also include HTML width
/height
to reserve space.
Does aspect-ratio
work if both width and height are set?
No. The property is ignored if both dimensions are fixed. Keep one dimension auto
.
What about images that crop badly?
Switch to object-fit: contain
to avoid cropping, or use object-position
to control the focal point when using cover
.
Do I still need the padding-box hack?
Only if you must support very old browsers. Otherwise, the native property is clearer, faster, and less error-prone.
Pre-publish checklist
- Use
aspect-ratio
for boxes, embeds, and placeholders. - Add HTML
width
/height
on images to prevent CLS. - Pick the right fit mode:
cover
vscontain
. - Test key breakpoints and landscape vs portrait viewports.
- Verify in Lighthouse/PageSpeed that CLS is stable and images are responsive.