Skip to main content

Overview

Aspect Ratio maintains a consistent width-to-height ratio for its child, regardless of the container width. It uses the CSS padding-bottom trick under the hood — no JavaScript resizing required.

Installation

npm install @araf-ds/core

Usage

import { AspectRatio } from "@araf-ds/core"

export default function Example() {
  return (
    <div className="w-full max-w-sm">
      <AspectRatio ratio={16 / 9}>
        <img
          src="/thumbnail.jpg"
          alt="Project thumbnail"
          className="rounded-lg object-cover w-full h-full"
        />
      </AspectRatio>
    </div>
  )
}

Variants

16:9 — Video / Widescreen

<AspectRatio ratio={16 / 9} className="bg-muted rounded-lg overflow-hidden">
  <video src="/intro.mp4" controls className="w-full h-full object-cover" />
</AspectRatio>

4:3 — Classic / Presentation

<AspectRatio ratio={4 / 3}>
  <img
    src="/slide.png"
    alt="Presentation slide"
    className="rounded-md object-cover w-full h-full"
  />
</AspectRatio>

1:1 — Square / Avatar / Product

<AspectRatio ratio={1 / 1} className="w-32">
  <img
    src="/product.jpg"
    alt="Product"
    className="rounded-full object-cover w-full h-full"
  />
</AspectRatio>

Responsive Image Grid

<div className="grid grid-cols-3 gap-3">
  {images.map(img => (
    <AspectRatio key={img.id} ratio={1 / 1}>
      <img
        src={img.src}
        alt={img.alt}
        className="rounded-md object-cover w-full h-full"
      />
    </AspectRatio>
  ))}
</div>

API Reference

ratio
number
default:"1"
The width-to-height ratio. Pass as a fraction: 16/9, 4/3, 1/1, 9/16.
className
string
Additional class names applied to the outer container.

Common Ratios

RatioValueUse Case
16 / 91.778Video, widescreen images, banners
4 / 31.333Classic photo, presentations
3 / 21.5Standard photography
1 / 11.0Square avatars, product thumbnails
9 / 160.5625Mobile / portrait video (Reels, TikTok)

Accessibility

  • AspectRatio is a purely layout utility — no ARIA roles needed
  • Ensure child images have descriptive alt text
  • For videos, ensure controls are visible or provide accessible custom controls
  • The container does not affect tab order or screen reader behavior

Do’s & Don’ts

Do

  • Always set a width on the parent container — AspectRatio fills 100% of its parent
  • Use object-cover on child images to fill without distortion
  • Apply overflow-hidden on the container when using border-radius
  • Use for images, videos, iframes, and map embeds

Don't

  • Don’t use AspectRatio for text content — height will clip text on small screens
  • Don’t nest AspectRatios — the inner one overrides the outer
  • Don’t forget to set the parent width — without it, the component has zero size
  • Don’t use object-contain with overflow-hidden — it creates letterboxing gaps