Aspect ratio
The height is known from the width before anything has loaded, so an image or an embed arriving late does not shove the rest of the page down. The child fills the box and is cropped rather than letterboxed.
Basic aspect ratio
aspectRatio({ ratio: '16 / 9', style: 'background: var(--su-surface-2)' },
'<img src="/logo.svg" alt="" style="object-fit: contain; padding: 2rem">',
)Common ratios
grid({ min: '9rem' },
...['16 / 9', '4 / 3', '1 / 1', '3 / 4'].map((ratio) =>
stack({ gap: 'xs' },
aspectRatio({ ratio, style: 'background: var(--su-surface-2); border-radius: 0.5rem' },
'<img src="/logo.svg" alt="" style="object-fit: contain; padding: 1rem">'),
text({ variant: 'caption', tone: 'muted', align: 'center' }, ratio),
),
),
)Embeds
The reason this component exists: an <iframe> has no intrinsic size, so without a ratio it collapses or needs a hard-coded height.
aspectRatio({ ratio: '16 / 9', style: 'background: var(--su-surface-2); border-radius: 0.6rem' },
'<div style="display: grid; place-items: center; color: var(--su-text-subtle)">an <iframe> would go here</div>',
)In a card
cardMedia() already does this for the top of a card. Reach for aspectRatio() when the box is somewhere else.
cardMedia — built in
aspectRatio — anywhere else
grid({ min: '12rem' },
card(
cardMedia({ src: '/logo.svg', alt: '', style: 'background: var(--su-surface-2); object-fit: contain; padding: 1rem' }),
cardBody(text({ variant: 'small' }, 'cardMedia — built in')),
),
card(
cardBody(
stack({ gap: 'sm' },
aspectRatio({ ratio: '1 / 1', style: 'background: var(--su-surface-2); border-radius: 0.5rem' },
'<img src="/logo.svg" alt="" style="object-fit: contain; padding: 1rem">'),
text({ variant: 'small' }, 'aspectRatio — anywhere else'),
),
),
),
)Cropping
The child is stretched to fill and cropped with object-fit: cover. For something that must not be cropped — a logo, a diagram — set object-fit: contain on the child, as every demo on this page does.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
ratio | string | '16 / 9' | Any CSS aspect-ratio value. |
as | string | 'div' | Element to render. |