Aspect Ratio
Displays content within a desired ratio. Useful for maintaining consistent proportions for images, videos, and embeds.
Docsimport { AspectRatio } from "~/components/aspect-ratio";
export default function AspectRatioBasicDemo() {
return (
<div class="w-full max-w-sm overflow-hidden rounded-md">
<AspectRatio ratio={16 / 9}>
<img
src="https://images.unsplash.com/photo-1588345921523-c2dcdb7f1dcd?w=800&auto=format&fit=crop&q=60"
alt="Image"
class="size-full rounded-md object-cover"
/>
</AspectRatio>
</div>
);
}Installation
CLI
Run the following command to add the component to your project:
npx @ark-preset/cli@latest add aspect-ratioManual
Create the recipe file at src/components/recipes/aspect-ratio.ts:
import { tv, type VariantProps } from "tailwind-variants";
export const aspectRatioVariants = tv({
base: "relative w-full",
});
export type AspectRatioVariants = VariantProps<typeof aspectRatioVariants>;Create the component file at src/components/aspect-ratio/index.tsx:
import { splitProps, type Component, children } from "solid-js";
import { aspectRatioVariants } from "../recipes/aspect-ratio";
import { ark, type HTMLArkProps } from "@ark-ui/solid/factory";
type AspectRatioProps = HTMLArkProps<"div"> & {
ratio?: number;
};
const AspectRatio: Component<AspectRatioProps> = (props) => {
const [local, others] = splitProps(props, ["class", "ratio", "children"]);
const resolvedChildren = children(() => local.children);
return (
<ark.div
class={aspectRatioVariants({ class: local.class })}
style={{ "padding-bottom": `${100 / (local.ratio ?? 16 / 9)}%` }}
{...others}
>
<ark.div class="absolute inset-0" style={{ position: "absolute", inset: 0 }}>
{resolvedChildren()}
</ark.div>
</ark.div>
);
};
export { AspectRatio, aspectRatioVariants };Note: Make sure your project has the Tailwind CSS theme variables set up (
--background,--foreground,--ring,--border, etc.) or override the utility classes to match your design system.
Usage
Basic Usage
import { AspectRatio } from "~/components/aspect-ratio";
export default function AspectRatioBasicDemo() {
return (
<div class="w-full max-w-sm overflow-hidden rounded-md">
<AspectRatio ratio={16 / 9}>
<img
src="https://images.unsplash.com/photo-1588345921523-c2dcdb7f1dcd?w=800&auto=format&fit=crop&q=60"
alt="Image"
class="size-full rounded-md object-cover"
/>
</AspectRatio>
</div>
);
}Square
Use a 1:1 aspect ratio to display square content.
Square Content
import { AspectRatio } from "~/components/aspect-ratio";
export default function AspectRatioSquareDemo() {
return (
<div class="w-full max-w-sm">
<AspectRatio ratio={1 / 1}>
<div class="flex size-full items-center justify-center rounded-md bg-muted text-sm text-muted-foreground">
Square Content
</div>
</AspectRatio>
</div>
);
}API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
ratio | number | 16/9 | The desired aspect ratio |
class | string | — | Additional CSS classes |