VayuUI

AspectRatio

A layout primitive that constrains children to a fixed aspect ratio using CSS aspect-ratio or padding-bottom fallback.

Installation

npx vayu-ui init #one time only
npx vayu-ui add aspectratio
npx vayu-ui add -t aspectratio #with test case needs

Usage

Preset Ratios

Built-in aspect ratio presets for common use cases.

Device Presets

Aspect ratios optimized for specific device screens.

Custom Numeric Ratio

Pass any numeric value for custom aspect ratios.

Object Fit Options

Control how images and videos fill the container.

Design System Props

Built-in props for rounded corners, shadows, and borders using design tokens.

Accessibility (Named Region)

Pass an aria-label to create a named landmark region for screen readers.

Foggy mountains during sunrise

Interactive Example

Combine AspectRatio with other components for interactive layouts.

Nature landscape
Mountain Vista

Explore the beauty of nature

Waterfall landscape
Waterfall Wonder

Discover hidden gems

<AspectRatio ratio="square" decorative className="rounded bg-ground-100 dark:bg-ground-800">
  <div className="flex items-center justify-center h-full text-sm text-muted-content">Square (1:1)</div>
</AspectRatio>

<AspectRatio ratio="video" decorative className="rounded bg-ground-100 dark:bg-ground-800">
  <div className="flex items-center justify-center h-full text-sm text-muted-content">Video (16:9)</div>
</AspectRatio>

<AspectRatio ratio={2.5} decorative className="rounded bg-ground-100 dark:bg-ground-800">
  <div className="flex items-center justify-center h-full text-sm text-muted-content">Custom (2.5)</div>
</AspectRatio>

<AspectRatio ratio="video" aria-label="Mountain landscape" bordered rounded>
  <img
    src="https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=800&q=80"
    alt="Mountain landscape"
  />
</AspectRatio>

Anatomy

import { AspectRatio } from 'vayu-ui';

<AspectRatio ratio="video" aria-label="Description">
  {/* Outer div with aspect-ratio constraint */}
  <div className="relative w-full aspect-video">
    {/* Inner wrapper fills the container */}
    <div className="absolute inset-0">{/* Your content renders here */}</div>
  </div>
</AspectRatio>;
  • Root — Outer <div> with the aspect ratio applied via Tailwind class (presets) or padding-bottom fallback (custom ratios). Manages overflow, accessibility roles, and design system tokens.
  • Inner — Absolutely positioned wrapper that fills the root container. Applies object-fit styles to direct <img> and <video> children.

Accessibility

  • Keyboard Support:
    • AspectRatio is a non-interactive layout primitive. No keyboard interactions are required.
  • ARIA Attributes:
    • When decorative is true: role="presentation" and aria-hidden="true" are applied, hiding the container from assistive technology.
    • When aria-label is provided: role="region" is applied, making the container a named landmark for screen readers.
    • When neither is set: no semantic role is added — the element is treated as a generic container.
  • Focus Behavior:
    • No focus management. The component delegates focus behavior to its children (e.g., links, buttons, interactive media).

Screen reader behavior

When decorative is set, the screen reader skips the container entirely — it will not be announced or included in the accessibility tree. When aria-label is provided, the screen reader identifies the container as a named region and announces the label when the user navigates into it (e.g., via landmarks or reading order). The content inside (images, videos, text) is announced normally based on its own semantics. When neither prop is set, the container is transparent to the screen reader and only its children are announced.

Component Folder Structure

AspectRatio/
├── AspectRatio.tsx    # Root component with UI + accessibility logic
├── types.ts           # TypeScript types, preset maps, and constant definitions
├── index.ts           # Re-exports component and types
└── README.md          # Component usage reference

Props

AspectRatio

PropTypeDefaultDescription
rationumber | AspectRatioPreset"square"Aspect ratio (width / height). Use a preset name or numeric value.
overflow"hidden" | "visible" | "auto" | "scroll""hidden"Overflow behaviour for the container.
objectFit"cover" | "contain" | "fill" | "scale-down" | "none""cover"Object-fit applied to direct <img> / <video> children.
decorativebooleanfalseMarks the container as decorative, hiding it from screen readers.
roundedbooleanfalseAdds rounded corners using design system tokens.
shadowbooleanfalseAdds subtle shadow using design system tokens.
borderedbooleanfalseAdds border using design system tokens.
aria-labelstringAccessible label for screen readers when content is meaningful.
classNamestringAdditional CSS classes.
childrenReactNodeContent to render inside the aspect ratio container.

On this page