AspectRatio
Constrains a child element to a given aspect ratio using a CSS custom property. A pure div-based implementation that uses aspect-(--ratio) — no padding-top hack required.
Anatomy
A single <AspectRatio ratio={n}> wrapper. The ratio prop is a number (width ÷ height). The child fills the constrained box using object-cover or absolute inset-0.
16:9
Common Ratios
Pass any numeric ratio to the ratio prop. Express it as a fraction for readability.
16:9
Widescreen video, hero images
4:3
Traditional display, old monitors
1:1
Profile photos, square thumbnails
3:2
Photography standard (DSLR)
2:3
Portrait / mobile screens
21:9
Ultrawide / cinematic
With Image
Place an <img> with object-cover w-full h-full inside the ratio wrapper to crop it to the target aspect.
16:9
1:1
2:3
Design Guidelines
Do
- Use for image and video containers. AspectRatio prevents layout shift while media loads by reserving the correct space.
- Express the ratio as a fraction.
ratio={16 / 9}is more readable thanratio={1.777}. - Combine with object-cover on images. This ensures the image fills the box without distortion.
Don't
- Don't use for text content. Text has natural height; forcing an aspect ratio will cause overflow or awkward whitespace.
- Don't use without constraining the wrapper width. Without a fixed width, the ratio box will expand to fill its parent.
- Don't mix absolute-positioned children with padding offsets. The component uses
aspect-(--ratio)— the child should fill viaabsolute inset-0orw-full h-full.
Developer Reference
API
ratio(required) — a number representing width ÷ height. Stored as a CSS custom property--ratio.- The component renders a plain
<div>— all standard div props are forwarded. - Children should use
w-full h-fullorabsolute inset-0to fill the box correctly.
Usage
import { AspectRatio } from "@/components/ui/aspect-ratio"
// Image at 16:9
<AspectRatio ratio={16 / 9}>
<img
src="/hero.jpg"
alt="Hero"
className="h-full w-full rounded-lg object-cover"
/>
</AspectRatio>
// Square placeholder
<AspectRatio ratio={1}>
<div className="flex h-full items-center justify-center bg-muted rounded-lg">
1:1
</div>
</AspectRatio>
// Portrait / mobile frame
<AspectRatio ratio={2 / 3}>
<div className="h-full w-full rounded-lg bg-muted" />
</AspectRatio>