Tessina UI
ConfiguratorGitHubIntroduction
InstallationUsageTheming
ComponentsAccordionAction SheetAlertAlertDialogArea ChartAspectRatioAvatarBadgeBannerBar ChartBottom NavBreadcrumbButtonButtonGroupCalendarCardCarouselChartChatBubbleCheckboxChipCodeBlockCollapsibleColor PickerComboboxCommandContainerContextMenuDate PickerDividerDrawerDropdown MenuEmptyStateFABFieldFieldsetFile UploadFile Upload 2FlexFormGridHoverCardIconButtonLabelLine ChartLinkMenubarMeterModalNavigation MenuNumberFieldOTP InputPaginationPie ChartPopoverProgressPromptInputRadar ChartRadial ChartRadioRatingScroll AreaSearchSegmentedControlSelectShortcutSidebarSkeletonSliderSpacerSpinnerSplit ButtonStackStatusStepperSurfaceSwitchTableTabsTextareaTime PickerToastToggleButtonToggleGroupToolbarTooltipTop Header DesktopTop Header Mobile
Contributing
Components

AspectRatio

Constrains content to a specific width/height ratio using CSS aspect-ratio. Seven named presets, arbitrary string or numeric ratios, eight corner-radius presets, automatic object-fit on single media children, and polymorphic render.

Playground

Installation

pnpm add @tessinaui/ui

Usage

import { AspectRatio } from "@tessinaui/ui";
{/* Named preset */}
<AspectRatio ratio="video" rounded="md">
  <img src="/hero.jpg" alt="" />
</AspectRatio>

{/* Custom numeric ratio */}
<AspectRatio ratio={21 / 9}>
  <img src="/panorama.jpg" alt="" />
</AspectRatio>

{/* Arbitrary CSS string */}
<AspectRatio ratio="2.35 / 1">
  <video src="/cinemascope.mp4" />
</AspectRatio>

{/* Object fit on single media children */}
<AspectRatio ratio="square" objectFit="cover">
  <img src="/avatar.jpg" alt="" />
</AspectRatio>

{/* Non-media content */}
<AspectRatio ratio="video" rounded="lg">
  <div className="grid place-items-center bg-primary-light">
    Placeholder
  </div>
</AspectRatio>

{/* Polymorphic — render as a figure */}
<AspectRatio ratio="portrait" render={<figure />}>
  <img src="/photo.jpg" alt="" />
</AspectRatio>

Examples

Default

A 16:9 video ratio wrapping an image with objectFit="cover".

Presets

Named presets — square, video, portrait, and landscape.

Custom ratios

Pass an arbitrary CSS string or a number for any ratio.

Object fit

Single media children get object-* applied — cover, contain, and fill.

Rounded

Corner-radius presets, which auto-apply overflow-hidden when non-none.

Polymorphic render

Render as a semantic <figure> element via the render prop.

Named ratios

Seven opinionated presets cover most common cases.

PresetRatioTypical use
"square"1 / 1Avatars, profile tiles
"video" (default)16 / 9Video thumbnails, hero banners
"portrait"3 / 4Phone-oriented photos
"landscape"4 / 3Classic photography
"ultrawide"21 / 9Panoramas, cinematic headers
"vertical"9 / 16Stories, TikTok, Reels
"golden"1.618 / 1Editorial layouts

Custom ratios

Pass a CSS-valid string or a number.

<AspectRatio ratio="7 / 5">…</AspectRatio>
<AspectRatio ratio={5 / 4}>…</AspectRatio>
<AspectRatio ratio="2.35 / 1">…</AspectRatio>

Under the hood this writes to style.aspectRatio, so anything the CSS aspect-ratio property accepts is valid.

Rounded

Corner-radius presets. When set to anything other than "none", overflow-hidden is added automatically so clipped children match the rounded corners.

ValueTailwind
"none" (default)—
"sm"rounded-sm
"md"rounded-md
"lg"rounded-lg
"xl"rounded-xl
"2xl"rounded-2xl
"3xl"rounded-3xl
"full"rounded-full

Object fit

Single <img> / <video> / <iframe> / <picture> children automatically receive block size-full, and objectFit maps to the corresponding Tailwind object-* class.

ValueTailwind
"cover"object-cover
"contain"object-contain
"fill"object-fill
"none"object-none
"scale-down"object-scale-down

Non-media children are absolutely positioned with inset-0 size-full.

Polymorphic render

Replace the default <div> with a semantic element.

<AspectRatio ratio="video" render={<figure />}>
  <img src="/photo.jpg" alt="" />
</AspectRatio>

Accessibility

  • AspectRatio is a structural primitive — it applies no ARIA roles.
  • Always provide alt text on <img> children — the wrapper does not carry any accessible name.
  • Use render={<figure />} + a <figcaption> sibling when the content benefits from a semantic caption.

API Reference

AspectRatio Props

PropTypeDefaultDescription
ratio"square" | "video" | "portrait" | "landscape" | "ultrawide" | "vertical" | "golden" or string or number"video"Target aspect ratio
rounded"none" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "full""none"Corner radius — auto-applies overflow-hidden when non-none
objectFit"cover" | "contain" | "fill" | "none" | "scale-down"—Applied to single media children as object-*
renderReactElement—Polymorphic target
classNamestring—Extra classes
styleCSSProperties—Custom styles — merged with aspect-ratio

Notes

  • Single-child convention. When you pass exactly one <img> / <video> / <iframe> / <picture> child it receives block size-full. Any other child (including multiple) is wrapped with absolute inset-0 size-full.
  • No hooks. Pure wrapper, safe for SSR.
  • Browser support. CSS aspect-ratio works in all modern browsers (Safari 15+, Chrome 88+, Firefox 89+).

Area Chart

Token-driven area chart built on Recharts v3 with gradient fills, stacking, single and multi-series support, and full light/dark theming via chart tokens.

Avatar

A circular (or rounded) user avatar that displays a profile image, 1–2 character initials, or a fallback icon. Supports six sizes, six initials color variants, an optional Status dot at any corner, full RTL layout, and an AvatarGroup for stacking.

On this page

PlaygroundInstallationUsageExamplesDefaultPresetsCustom ratiosObject fitRoundedPolymorphic renderNamed ratiosCustom ratiosRoundedObject fitPolymorphic renderAccessibilityAPI ReferenceAspectRatio PropsNotes