ComponentsLayout

Aspect Ratio

Keeps content at a fixed shape as its width changes. Use it for images, video, and the placeholders that hold their space.

Image ratios

The three ratios the playground shows: 16:9, 4:3, and square. Each frame fills its column up to 288px, and the image covers the frame.

Fictional green landscape
Ratio 1.78
Fictional green landscape
Ratio 1.33
Fictional green landscape
Ratio 1.00

Change the ratio

The ratio is a number, so it can change at runtime. The frame keeps its width and the height follows.

Fictional green landscape

16:9 · Ratio 1.78 · Video and cover images

Reserved space

The frame holds its height before the image arrives, so the page does not jump. Put a placeholder or a fallback inside it.

Loading preview…
Loading
Preview unavailable
Image failed
No cover image yet. Upload one in project settings to show it here.
Empty, long text

Usage

Aspect Ratio usageTSX
import { AspectRatio } from "@tulipfarm/sprout/aspect-ratio";

<div className="w-full max-w-72 overflow-hidden rounded-xl">
  <AspectRatio ratio={16 / 9}>
    <img
      src="/landscape.svg"
      alt="Fictional green landscape"
      className="size-full object-cover"
    />
  </AspectRatio>
</div>

ratio is required. It is width divided by height, so16 / 9, 4 / 3, and 1 give wide, photo, and square frames. The frame takes the full width it is given and sets its height from the ratio. Content taller than the frame does not stretch it.

The frame is a div with position: relative anddata-slot="aspect-ratio". It takes all div props.className and style merge with its own, and the ratio is set as --sprout-aspect-ratio. Make children fill it with size-full, or place them with absolute inset-0.

The frame does not round or clip. Wrap it, or pass className, with overflow-hidden and a radius when the corners should be round.

Accessibility

Aspect Ratio adds no role and no focus stop. Give images realalt text. While content loads, put aria-busy on the frame and a role="status" placeholder inside it.