Getting StartedComponentsDesign TokensThemingTheme SynthesizerFrameworksAccessibilityUtilitiesServer RenderingBrowser SupportContributingChangelog App ShellAspect GridAuth ShellCenterClusterContainerDashboard GridDockFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbar Anchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkSpeed DialStepper NavTabsTop BarTree View AccordionAspect RatioAvatarAvatar GroupCalloutCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSeparatorSkeletonSpinnerStackVideoVirtual List Activity HeatmapAnimated NumberBadgeChartClockComparisonCountdown TimerData GridData TableDescription ListDiffEvent CalendarGaugeJSON TreeKanbanKey ValueLevel MeterListMeterSparklineStatStepperTableTagTimelineUptimeValue CardWaveform BlockquoteCode BlockGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriter ButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputOTP InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree Select AlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuGuided TourHover CardInline MessageLoading OverlayModalNotification PanelPopoverProgressProgress ToastSheetSnackbarSpotlightToastTooltip
ARC UI ARC Radiant Components
v3.2 Docs Components Tokens Synthesizer
Getting StartedFrameworksServer Rendering Design TokensThemingTheme SynthesizerTypographyUtilities All ComponentsAccessibilityBrowser SupportChangelogContributingStats App ShellAspect GridAuth ShellCenterClusterContainerDashboard GridDockFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbar Anchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkMenubarNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkSpeed DialStepper NavTabsTop BarTree View AccordionAspect RatioAvatarAvatar GroupCalloutCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageImage CompareImage HotspotsInfinite ScrollLightboxMarqueeQR CodeScroll AreaSeparatorSkeletonSpinnerStackVideoVirtual List Activity HeatmapAnimated NumberBadgeChartClockComparisonCountdown TimerData GridData TableDescription ListDiffEvent CalendarGaugeJSON TreeKanbanKey ValueLevel MeterListMeterSparklineStatStepperTableTagTimelineUptimeValue CardWaveform BlockquoteCode BlockGradient TextHighlightKbdKeyboard MapMarkdownNumber FormatProseTerminalTextTime AgoTruncateTypewriter ButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerDate Range PickerFieldsetFile UploadFormHotkeyIcon ButtonImage CropperInline EditInputInput GroupKnobLabelMasked InputMulti SelectNumber InputOTP InputPassword InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSignature PadSliderSortable ListSwitch GroupTag InputTextareaTheme ToggleTime PickerToggleTransfer ListTree Select AlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuConversationDialogDropdown MenuGuided TourHover CardInline MessageLoading OverlayModalNotification PanelPopoverProgressProgress ToastSheetSnackbarSpotlightToastTooltip

Aspect Ratio

Container that enforces a consistent width-to-height ratio on its content, ideal for images, videos, and embedded media.

Components Aspect Ratio
content static
<arc-aspect-ratio>

Overview

AspectRatio is a layout primitive that constrains its children to a specified width-to-height proportion using the CSS `aspect-ratio` property. Pass a ratio string like `"16/9"`, `"4/3"`, or `"1/1"` and the container will maintain that shape regardless of the available width. Slotted children (images, videos, iframes) are automatically sized to fill the container with `object-fit: cover`, ensuring no letterboxing or stretching. This component solves the common problem of content layout shift (CLS) caused by media loading. By reserving the exact space an image or video will occupy before it loads, AspectRatio prevents the jarring page reflows that hurt both user experience and Core Web Vitals scores. The container's width is always 100% of its parent, and the height is derived from the ratio, so it works seamlessly in fluid grid layouts. The ratio prop accepts any valid `W/H` format including decimal values like `"2.35/1"` for cinematic widescreen. If an invalid format is provided, the component falls back to `16/9`. The container applies the theme's medium border radius and clips overflow, so rounded corners on media come free without additional styling.

Guidelines

When to use

  • Use AspectRatio around images and videos to prevent layout shift during page load
  • Choose standard ratios that match your media: `16/9` for video, `4/3` for photos, `1/1` for avatars or thumbnails
  • Place AspectRatio inside grid or flex containers where the width is determined by the layout
  • Use decimal ratios like `2.35/1` for cinematic or ultrawide content when needed
  • Combine with lazy loading on images for optimal performance — the space is reserved before the image loads

When not to use

  • Do not use AspectRatio when the content has its own intrinsic dimensions and layout shift is not a concern
  • Do not place text-heavy content inside AspectRatio — it clips overflow and does not scroll
  • Do not set both a fixed height and AspectRatio on the same element — they will conflict
  • Do not use ratio values with zero in the denominator (e.g. `16/0`) — the component falls back to 16/9
  • Avoid nesting multiple AspectRatio components — the inner one will be constrained by both ratios unpredictably

Features

  • Enforces a consistent aspect ratio using the CSS `aspect-ratio` property with a `W/H` string prop
  • Slotted children automatically sized to fill with `width: 100%`, `height: 100%`, and `object-fit: cover`
  • Prevents content layout shift (CLS) by reserving space before media loads
  • Supports any valid ratio including standard formats (`16/9`, `4/3`, `1/1`) and decimals (`2.35/1`)
  • Falls back to `16/9` if the ratio string is invalid or malformed
  • Applies `border-radius: var(--radius-md)` with overflow clipping for rounded media corners
  • Full-width container that fills its parent, making it ideal for responsive grid cells
  • Lightweight wrapper with no JavaScript interaction — purely CSS-driven layout

Preview

16 / 9

Usage

<arc-aspect-ratio ratio="16/9">
  <img src="/hero.jpg" alt="Hero banner" />
</arc-aspect-ratio>

<!-- Square thumbnail -->
<arc-aspect-ratio ratio="1/1">
  <img src="/avatar.jpg" alt="User avatar" />
</arc-aspect-ratio>
import { AspectRatio } from '@arclux/arc-ui-react';

export default function Example() {
  return (
    <>
      <AspectRatio ratio="16/9">
        <img src="/hero.jpg" alt="Hero banner" />
      </AspectRatio>

      {/* Square thumbnail */}
      <AspectRatio ratio="1/1">
        <img src="/avatar.jpg" alt="User avatar" />
      </AspectRatio>
    </>
  );
}
<script setup>
import { AspectRatio } from '@arclux/arc-ui-vue';
</script>

<template>
  <AspectRatio ratio="16/9">
    <img src="/hero.jpg" alt="Hero banner" />
  </AspectRatio>

  <!-- Square thumbnail -->
  <AspectRatio ratio="1/1">
    <img src="/avatar.jpg" alt="User avatar" />
  </AspectRatio>
</template>
<script>
  import { AspectRatio } from '@arclux/arc-ui-svelte';
</script>

<AspectRatio ratio="16/9">
  <img src="/hero.jpg" alt="Hero banner" />
</AspectRatio>

<!-- Square thumbnail -->
<AspectRatio ratio="1/1">
  <img src="/avatar.jpg" alt="User avatar" />
</AspectRatio>
import { Component } from '@angular/core';
import { AspectRatio } from '@arclux/arc-ui-angular';

@Component({
  imports: [AspectRatio],
  template: `
    <arc-aspect-ratio ratio="16/9">
      <img src="/hero.jpg" alt="Hero banner" />
    </arc-aspect-ratio>

    <!-- Square thumbnail -->
    <arc-aspect-ratio ratio="1/1">
      <img src="/avatar.jpg" alt="User avatar" />
    </arc-aspect-ratio>
  `,
})
export class MyComponent {}
import { AspectRatio } from '@arclux/arc-ui-solid';

export default function Example() {
  return (
    <>
      <AspectRatio ratio="16/9">
        <img src="/hero.jpg" alt="Hero banner" />
      </AspectRatio>

      {/* Square thumbnail */}
      <AspectRatio ratio="1/1">
        <img src="/avatar.jpg" alt="User avatar" />
      </AspectRatio>
    </>
  );
}
import { AspectRatio } from '@arclux/arc-ui-preact';

export default function Example() {
  return (
    <>
      <AspectRatio ratio="16/9">
        <img src="/hero.jpg" alt="Hero banner" />
      </AspectRatio>

      {/* Square thumbnail */}
      <AspectRatio ratio="1/1">
        <img src="/avatar.jpg" alt="User avatar" />
      </AspectRatio>
    </>
  );
}
<!-- Auto-generated by @arclux/prism — do not edit manually -->
<!-- arc-aspect-ratio — requires aspect-ratio.css + tokens.css (or arc-ui.css) -->
<div class="arc-aspect-ratio">
  <div
    class="aspect-ratio"
    style="aspect-ratio: _aspect Ratio;"
  >
    <div class="aspect-ratio__inner">
      AspectRatio
    </div>
  </div>
</div>
<!-- Auto-generated by @arclux/prism — do not edit manually -->
<!-- arc-aspect-ratio — self-contained, no external CSS needed -->
<div class="arc-aspect-ratio" style="display: block">
  <div
    style="position: relative; width: 100%; overflow: hidden; border-radius: 10px"
    style="aspect-ratio: _aspect Ratio;"
  >
    <div style="width: 100%; height: 100%">
      AspectRatio
    </div>
  </div>
</div>

API

ratio string '16/9'
Aspect ratio as a `W/H` string. Supports integers and decimals. Falls back to `16/9` if invalid.

See Also