A CSS-native ratio frame that reserves space for media and safely handles invalid ratio values.
import { AspectRatio } from "@/components/ballmac/aspect-ratio"
export default function AspectRatioDemo() {
return (
<div className="w-full max-w-sm overflow-hidden rounded-xl border bg-card shadow-sm">
<AspectRatio ratio={16 / 9} className="bg-muted">
<div className="flex size-full items-center justify-center bg-gradient-to-br from-primary/20 via-background to-chart-2/20">
<div className="rounded-xl border bg-card/90 px-6 py-4 text-center shadow-sm">
<div className="text-sm font-semibold">Quarterly overview</div>
<div className="mt-1 text-xs text-muted-foreground">
A clearer view of your work
</div>
</div>
</div>
</AspectRatio>
<div className="p-4 text-sm font-medium">
A story with room to breathe
</div>
</div>
)
}Installation
$ pnpm dlx shadcn@latest add @ballmac/aspect-ratioCopy the source into your project.
components/ballmac/aspect-ratio.tsx// Ballmac UI: Aspect Ratio. https://ui.ballmac.com/components/aspect-ratio // Based on shadcn/ui Aspect Ratio (MIT, Copyright (c) 2023 shadcn), adding a native CSS fallback for invalid ratios. import * as React from "react" import { cn } from "@/lib/utils" type AspectRatioProps = React.ComponentProps<"div"> & { /** Width divided by height. Defaults to 16:9. */ ratio?: number } function AspectRatio({ ratio = 16 / 9, className, style, ...props }: AspectRatioProps) { const safeRatio = Number.isFinite(ratio) && ratio > 0 ? ratio : 16 / 9 return ( <div data-slot="aspect-ratio" className={cn( "relative w-full overflow-hidden rounded-[inherit] [&>*]:size-full", className, )} style={{ aspectRatio: safeRatio, ...style }} {...props} /> ) } export { AspectRatio, type AspectRatioProps }Update the import paths to match your project setup.
Usage
import { AspectRatio } from "@/components/ballmac/aspect-ratio"The full example is in the Code tab above.
Examples
States and variants
import { AspectRatio } from "@/components/ballmac/aspect-ratio"
export default function AspectRatioStates() {
return (
<div className="grid w-full max-w-md grid-cols-2 gap-3">
<AspectRatio ratio={1} className="rounded-xl bg-primary/10">
<div className="flex items-center justify-center text-sm font-medium">
1:1
</div>
</AspectRatio>
<AspectRatio ratio={4 / 3} className="rounded-xl bg-chart-2/10">
<div className="flex items-center justify-center text-sm font-medium">
4:3
</div>
</AspectRatio>
</div>
)
}API reference
| Prop | Type | Default |
|---|---|---|
ratioWidth divided by height. Defaults to 16:9. | number | 16 / 9 |
Also accepts the standard attributes of its root element.
Use with AI
A CSS-native ratio frame that reserves space for media and safely handles invalid ratio values. With the shadcn MCP server set up (guide), ask your agent:
Add the Ballmac UI Aspect Ratio (@ballmac/aspect-ratio) to this project with the shadcn MCP, then use it where it fits.
Use it for
- Reserve image or video space before it loads
- Keep cards aligned across a grid
Not for
- Use fixed height when cropping is intentional
Registry JSON: https://ui.ballmac.com/r/aspect-ratio.json
Credits
Based on shadcn/ui Aspect Ratio, adapted by Ballmac. Free to use in personal and commercial projects.
- npm
- None
- Registry
- shadcn/utils
Pairs well with
Card
A composable content surface with compact spacing, an action slot, and optional interactive feedback.
App Shell
The frame of an application page: skip link, sticky header, sidebar that becomes a sheet on small screens, main area, optional aside and footer.
Bento Grid
A responsive bento layout of feature cards that span columns and rows. Each BentoCard has a background visual slot, icon, title and description, and a link that slides up on hover or focus.
Container Scroll
A showcase frame that starts tilted back in 3D and flattens to face the reader as it scrolls into view, with a title that lifts alongside.