v0.5

Aspect Ratio

Reserves a fixed width-to-height ratio for media and embeds so the layout stays put while they load.

Description

AspectRatio is a single-element wrapper rendered as a <div>. It wraps Radix's AspectRatio.Root and forces its single child to fit a width-to-height ratio you specify via the ratio prop.

Reach for it when a media slot must reserve space before its asset paints. Typical cases: image thumbnails in lists and grids, video and iframe embeds (YouTube, Vimeo, Loom), and hero media on cards. Locking the slot prevents layout shift when the asset finally loads.

Don't use AspectRatio for text content that should wrap naturally, or as a generic flex / grid sizer. If the child already has a known intrinsic size (a fixed SVG icon, a sized button), skip it. If the layout only needs a minimum height, reach for Tailwind sizing utilities directly.

Installation

pnpm dlx @create-ui/cli add aspect-ratio

Usage

import { AspectRatio } from "@/components/ui/aspect-ratio"
<AspectRatio ratio={16 / 9}>
  <img src="/photo.jpg" alt="" />
</AspectRatio>

Examples

Landscape

ratio={16 / 9} is the default media aspect. Use it for video thumbnails, hero images, and any photo-first card cover.

Square

ratio={1} keeps width and height equal. Reach for it on product tiles, gallery grids, and avatar-style media.

Portrait

ratio={9 / 16} flips the slot vertical. Use it for mobile stories, reels, and any vertical video preview.

Common ratios

The design system catalogues a set of named ratios. Any positive number works for the ratio prop, but these are the canonical values used across the library:

Nameratio value
Square1
Classic4 / 3
Photo3 / 2
Post4 / 5
Wide2
Landscape16 / 9
Social1.91
Cinematic21 / 9
Banner4
Classic Portrait3 / 4
Photo Portrait2 / 3
Portrait9 / 16
Wide Portrait1 / 2

The list is a convention, not a constraint. Pass any positive number you need, including custom values like ratio={1920 / 1080}.

Accessibility

AspectRatio is a passive layout primitive. It renders a plain <div> and has no keyboard interactions or focus behavior; the consumer is responsible for labelling the child media.

KeyDescription
-Not focusable by default.

ARIA notes:

  • The component sets no implicit role. Treat it as a layout box, not as semantic structure.
  • Label the child, not the wrapper: alt on <img>, title on <iframe>, an aria-label on the video container when no caption is visible.
  • For purely decorative media, add aria-hidden="true" on the child so assistive tech skips it.
  • Built on Radix's AspectRatio primitive. See Radix's docs for primitive-level behavior.

Styling

Tailwind override: pass className to merge Tailwind classes with the component's base classes (via cn()):

<AspectRatio ratio={16 / 9} className="bg-bg-weak overflow-hidden rounded-lg">
  <img src="/photo.jpg" alt="" className="object-cover" />
</AspectRatio>

Data slots and attributes: the component sets these for CSS targeting:

  • data-slot="aspect-ratio" on the root <div>.
  • The component sets no data-* state or variant attributes; there is no CVA axis to expose.

Target the slot directly in CSS:

[data-slot="aspect-ratio"] {
  border-radius: var(--radius-lg);
}
  • Avatar: when the media is specifically a circular user portrait.
  • Card: when the surface chrome (border, padding, radius) is the goal and the aspect is a side effect.
  • Skeleton: when reserving space for non-media content (text lines, blocks) before data loads.

API Reference

AspectRatio

Reserves a fixed width-to-height ratio for its single child. Wraps Radix's AspectRatio.Root, so it accepts any standard <div> attribute (id, role, aria-*, onClick, etc.) plus Radix's primitive props.

Props

PropTypeDefaultDescription
rationumber1Desired width-to-height ratio. Use math expressions like 16 / 9 for readability.
asChildbooleanfalseRender the underlying element as the only child via Radix Slot. (advanced)
classNamestring-Tailwind classes merged with the component's base classes via cn().
childrenReact.ReactNode-The single media element (<img>, <video>, <iframe>, etc.) sized to the ratio.