Skip to main content

AspectRatio

Available from version 0.5.0

The Aspect Ratio component resizes its contents to match the desired ratio.

Basics

import { AspectRatio } from 'tailwind-joy/components';

The Aspect Ratio component wraps around the content that it resizes. The element to be resized must be the first direct child. The default ratio is 16/9.

import { AspectRatio, Typography } from 'tailwind-joy/components';

export function AspectRatioBasics() {
return (
<AspectRatio className="w-[300px]">
<Typography level="h2" component="div">
16/9
</Typography>
</AspectRatio>
);
}

Customization

Variants

The Aspect Ratio component supports four variants: solid, soft (default), outlined, and plain.

import { AspectRatio, Box, Typography } from 'tailwind-joy/components';

export function AspectRatioVariants() {
return (
<Box className="flex w-full gap-4">
<Box className="flex-1">
<AspectRatio variant="solid">
<Typography level="inherit" className="font-semibold">
Solid
</Typography>
</AspectRatio>
</Box>
<Box className="flex-1">
<AspectRatio variant="soft">
<Typography level="inherit" className="font-semibold">
Soft
</Typography>
</AspectRatio>
</Box>
<Box className="flex-1">
<AspectRatio variant="outlined">
<Typography level="inherit" className="font-semibold">
Outlined
</Typography>
</AspectRatio>
</Box>
<Box className="flex-1">
<AspectRatio variant="plain">
<Typography level="inherit" className="font-semibold">
Plain
</Typography>
</AspectRatio>
</Box>
</Box>
);
}

Ratio

Use the ratio prop to change the aspect ratio, following the pattern width/height. For example, the demo below uses a ratio of 4/3, which is a common alternative to the default 16/9:

import { AspectRatio, Typography } from 'tailwind-joy/components';

export function AspectRatioRatio() {
return (
<AspectRatio
variant="outlined"
ratio="4/3"
className="bg-joy-neutral-200 dark:bg-joy-neutral-700 w-[300px] rounded-lg"
>
<Typography level="h2" component="div">
4/3
</Typography>
</AspectRatio>
);
}

Object fit

When the content inside the Aspect Ratio component is an image or a video, you can use the objectFit prop to control how it's resized.

This prop gives you access to all of the values associated with the CSS object-fit property: cover (default), contain, fill, scaleDown, initial, inherit, and none.

import { AspectRatio, Box } from 'tailwind-joy/components';

export function AspectRatioObjectFit() {
return (
<Box className="w-[300px] rounded-md p-2">
<AspectRatio objectFit="contain">
<img
src="https://images.unsplash.com/photo-1502657877623-f66bf489d236?auto=format&fit=crop&w=800"
srcSet="https://images.unsplash.com/photo-1502657877623-f66bf489d236?auto=format&fit=crop&w=800&dpr=2 2x"
alt="A beautiful landscape."
/>
</AspectRatio>
</Box>
);
}

Media placeholder

Use a <div>, or a Box component paired with an icon, as a fallback when there is no media content provided:

Title

Description of the card.

import { MdImage } from 'react-icons/md';
import { AspectRatio, Sheet, Typography } from 'tailwind-joy/components';
import { iconClass } from 'tailwind-joy/utils';
import { twMerge } from 'tailwind-merge';

export function AspectRatioMediaPlaceholder() {
return (
<Sheet
variant="outlined"
className="mx-auto flex w-full max-w-[300px] flex-col gap-y-3 rounded-lg p-4"
>
<AspectRatio>
<div>
<MdImage
className={twMerge(
iconClass(),
'text-[3rem] text-[color:inherit] opacity-20 dark:text-[color:inherit]',
)}
/>
</div>
</AspectRatio>
<div>
<Typography level="title-md">Title</Typography>
<Typography level="body-sm">Description of the card.</Typography>
</div>
</Sheet>
);
}

Minimum and maximum height

Use the minHeight and maxHeight props to set the lower and upper bound for the height of the content. This is useful when the Aspect Ratio component wraps dynamic-width content, as shown in the demo below:

import { AspectRatio, Box } from 'tailwind-joy/components';

export function AspectRatioMinimumAndMaximumHeight() {
return (
<Box className="w-[300px] resize-x overflow-auto p-2">
<AspectRatio minHeight={120} maxHeight={200}>
<img
src="https://images.unsplash.com/photo-1502657877623-f66bf489d236?auto=format&fit=crop&w=800"
srcSet="https://images.unsplash.com/photo-1502657877623-f66bf489d236?auto=format&fit=crop&w=800&dpr=2 2x"
alt=""
/>
</AspectRatio>
</Box>
);
}

Anatomy

The Aspect Ratio component is composed of a root <div> with a content <div> nested inside; the child component is given a data-first-child attribute for styling purposes:

<div class="tj-aspect-ratio-root ...">
<div class="tj-aspect-ratio-content ...">
<some-element data-first-child>
<!-- Aspect Ratio contents -->
</some-element>
</div>
</div>

API

See the documentation below for a complete reference to all of the props available to the components mentioned here.