AspectRatio

A layout primitive that constrains its content to a fixed width-to-height ratio.

Overview

An AspectRatio reserves a box at a fixed width-to-height ratio using the native CSS aspect-ratio property — the classic use is holding responsive media (an image, a video, a map embed) so the layout doesn’t reflow while the asset loads. It fills the available width and derives its height from the ratio.

Anatomy

A single <div> set to width: 100%, the given aspect-ratio, and overflow: hidden. Size a single child to width: 100%; height: 100% (e.g. an <img> with object-fit: cover) to fill the box. There is no sketch layer — this primitive is purely structural.

Variants & States

AspectRatio is a static layout box — it has no interactive states. The only variation is the ratio value itself.

State Status Notes
Hover Not implemented Not interactive.
Focus Not implemented Not focusable.
Disabled Not implemented —
Loading Not implemented —
Error Not implemented —

Usage

Do

  • Place a single child sized to width: 100%; height: 100% (an <img> with object-fit: cover is the common case).
  • Pass the ratio as a number expression like 16 / 9 or 4 / 3 so intent stays readable.
  • Constrain the outer width (e.g. a max-width wrapper) — the box derives its height from that width.

Don't

  • Don't set an explicit height on the box — the ratio derives it from the width.
  • Don't use it purely to add spacing; it's for reserving media proportions, not general layout gaps.

Accessibility

Content

N/A — AspectRatio has no fixed content model. Content is whatever single element you place inside, sized to fill the box.

Props API

React@ghds/react

PropTypeDefaultDescription
rationumber1Desired width-to-height ratio, e.g. 16 / 9 for widescreen or 1 for a square.
...restHTMLAttributes<HTMLDivElement>—Native <div> attributes (className, style, etc.) pass through.

Web Components@ghds/web-components

PropTypeDefaultDescription
rationumber1Reflected attribute; sets the host aspect-ratio. Slot a single child to fill the box.

React Native@ghds/react-native

PropTypeDefaultDescription
rationumber1Width-to-height ratio applied via the native aspectRatio style.
childrenReactNode—Content constrained to the ratio box.
styleStyleProp<ViewStyle>—Extra style merged onto the ratio box.
accessibilityLabelstring—Accessible label for the region.
testIDstring—Test handle for queries.

Code examples

// React — @ghds/react
import { AspectRatio } from '@ghds/react/aspect-ratio';

<AspectRatio ratio={16 / 9}>
  <img src="https://example.com/cover.jpg" style={{ width: '100%', height: '100%', objectFit: 'cover' }} />
</AspectRatio>;
<!-- Web Components — @ghds/web-components -->
<script type="module">
  import '@ghds/web-components/aspect-ratio';
</script>
<gh-aspect-ratio ratio="1.7778">
  <img src="https://example.com/cover.jpg" style="width: 100%; height: 100%; object-fit: cover;" />
</gh-aspect-ratio>
// React Native — @ghds/react-native
import { AspectRatio } from '@ghds/react-native/aspect-ratio';
import { Image } from 'react-native';

<AspectRatio ratio={16 / 9}>
  <Image
    source={{ uri: 'https://example.com/cover.jpg' }}
    style={{ width: '100%', height: '100%' }}
    resizeMode="cover"
  />
</AspectRatio>;

Live Demo

React and Web Components render live below, driven by the same tokens — toggle dark mode in the header to see both respond identically. React Native can’t run in a browser without additional react-native-web wiring (not set up in this site), so its usage is shown as a code sample instead.

React @ghds/react

Web Components @ghds/web-components

16 / 9
1 / 1
4 / 3