Installation
pnpm dlx shadcn@latest add https://rdf.dev.360online.com/r/aspect-ratio.jsonInstalls to @/components/ui/aspect-ratio.
Manual installation
Copy the source into your project:
import type * as React from 'react'
import { cn } from '@/lib/utils'
function AspectRatio({ ratio = 1, className, style, ...props }: React.ComponentProps<'div'> & { ratio?: number }) {
return (
<div
data-slot="aspect-ratio"
style={{ '--ratio': ratio, ...style } as React.CSSProperties}
className={cn('relative aspect-(--ratio)', className)}
{...props}
/>
)
}
export { AspectRatio }Displays content within a desired ratio. The Aspect Ratio component uses the CSS aspect-ratio property and keeps images, maps, video embeds and document previews at fixed proportions regardless of the available width.
Features
- Any numeric ratio, e.g. 16 / 9, 4 / 3 or 1
- Scales with its container width
- Works with images, iframes and arbitrary content
- Plain CSS
aspect-ratio, no primitive dependency
Usage
import { AspectRatio } from '@/components/ui/aspect-ratio'
export function CityHallImage() {
return (
<div className="w-full max-w-md">
<AspectRatio ratio={16 / 9} className="rounded-lg bg-muted">
<img src="/city-hall.jpg" alt="City hall seen from the main square" className="h-full w-full rounded-lg object-cover" />
</AspectRatio>
</div>
)
}ratio defaults to 1. The component is a single div with position: relative and the CSS aspect-ratio, so
className styles the ratio box itself and children can be placed with absolute too.
Examples
Default
A 16:9 image slot with a caption. The examples use token-based placeholders where your app would show a photo.
Square
1:1 thumbnails for a grid of municipal facilities.
Portrait
An A4 ratio (1 / Math.SQRT2) for a preview of a scanned or generated document.
Map Embed
A 4:3 container for an embedded property map, with overlays positioned on top.
Video
A 16:9 frame for a recorded council meeting, with a play button and duration.
Accessibility
- Purely presentational: it does not add any roles or semantics
- Always provide meaningful alt text for images placed inside
- Give embedded iframes a descriptive title attribute