Skip to main content

aspect ratio

Displays content within a desired ratio.

Philosophy

Responsive media needs dimensional constraints. AspectRatio solves the CSS aspect-ratio problem with a clean component API, preventing layout shifts when images and videos load. The ratio prop is the only knob you need - everything else is handled by the container's CSS.

How It's Built

Loading diagram...

Installation


npx @gentleduck/cli add aspect-ratio

npx @gentleduck/cli add aspect-ratio

Usage

import Image from "next/image"
 
import { AspectRatio } from "@/components/ui/aspect-ratio"
import Image from "next/image"
 
import { AspectRatio } from "@/components/ui/aspect-ratio"
<div className="w-[450px]">
  <AspectRatio ratio={16 / 9}>
    <Image src="..." alt="Image" className="rounded-md object-cover" />
  </AspectRatio>
</div>
<div className="w-[450px]">
  <AspectRatio ratio={16 / 9}>
    <Image src="..." alt="Image" className="rounded-md object-cover" />
  </AspectRatio>
</div>

RTL Support

Direction is resolved through the shared primitives direction module. Use a local dir="rtl" override when the component exposes it, or set DirectionProvider at app/root level for global RTL/LTR behavior.

Motion

Use MotionAspectRatio for a smooth scale + blur entrance animation powered by motion. The content scales from 0.95 and unblurs on mount.

API Reference

AspectRatio

PropTypeDefaultDescription
dir'ltr' | 'rtl'-Text direction override. Resolved via useDirection (dir prop -> DirectionProvider -> 'ltr').
rationumber(required)Aspect ratio of the container, e.g. 16/9, 4/3
classNamestring--Additional class names to apply to the container
styleReact.CSSProperties--Inline styles applied to the container (aspect-ratio is merged automatically)
childrenReact.ReactNode--Child element to render inside the aspect-ratio container
...propsReact.ComponentPropsWithoutRef<typeof Slot>-Additional props inherited from Slot.

Uses a Slot wrapper, so the child element receives the aspect-ratio styles.

MotionAspectRatio

Renders a div (not Slot) that scales from 0.95 with 8px blur fade on mount using contentTransition (250ms expo-out). Requires the motion package.

PropTypeDefaultDescription
...propsAspectRatioProps-All props from AspectRatio are supported