JGuang

AspectRatio

AspectRatio · Astryx

Preview
npm install @astryxdesign/core@0.7.1 @astryxdesign/theme-neutral@0.7.1 @stylexjs/stylex@0.19.0

AspectRatio

Maintains a fixed width-to-height ratio for its children as its container resizes. Use it for media containers like videos, images, thumbnails, or any content that needs consistent proportions. It takes its width from the container and derives its height from the ratio, so it needs an ancestor with a definite width.

Installation

npm install @astryxdesign/core@0.7.1 @astryxdesign/theme-neutral@0.7.1 @stylexjs/stylex@0.19.0

Requires React 19+, base CSS and a Theme provider. See Setup.

Aspect Ratio

Maintains a fixed width-to-height ratio for its children as its container resizes. Use it for media containers like videos, images, thumbnails, or any content that needs consistent proportions. It takes its width from the container and derives its height from the ratio, so it needs an ancestor with a definite width.

PropTypeDefaultDescription
ratio *numberAspect ratio as width/height (e.g. 16/9, 1). Emitted as a class-level declaration (never inline), so xstyle rules or unlayered consumer CSS can override it responsively.
shape'rectangle' | 'ellipse''rectangle'Container shape. Both respect the ratio. ellipse clips to an oval (a circle when ratio={1}).
fit'cover' | 'contain' | 'center'How the child is sized inside the ratio box. cover fills and crops media, contain fills and letterboxes, center keeps the natural size centered. When omitted, the child styles itself.
children *ReactNodeContent positioned absolutely to fill the container.
xstyleStyleXStylesStyleX styles for layout customization (margins, positioning, sizing). Must be a stylex.create() value, not an inline style object like style={{}}.

Usage guidance

  • Express the ratio as a fraction for readability — ratio={16 / 9} rather than ratio={1.78}. It is a number, so the string form ratio="16/9" is a type error.
  • Use for media that needs consistent proportions across screen sizes.
  • Use fit="cover" for images and video so the component sizes the child; the child should not repeat width/height/objectFit styles.
  • Pass one child. With fit set, every direct child is stretched to fill the box, so put an overlay or caption inside a single wrapper child rather than passing it as a second child.
  • Describe media children with alt, or alt="" when the image is decorative. AspectRatio adds no role and no accessible name of its own, so the child carries the whole accessible description.
  • For a breakpoint-dependent ratio, override the ratio responsively: pass an aspectRatio rule via xstyle (StyleX), or override aspect-ratio from your own unlayered CSS under a @media/@container rule; component styles live in the astryx-base cascade layer, so unlayered consumer CSS wins. Give an xstyle rule a default branch alongside the conditional one ({default: 3, '@container ...': '3 / 2'}); with only the conditional branch the ratio is unset outside the query and the box collapses.
  • Avoid: Use for general layout containers; use standard layout components instead.
  • Avoid: Nest AspectRatio containers; one level is sufficient.
  • Avoid: Constrain the height on its own. The width comes from the container, so a height or maxHeight by itself clamps the box off ratio; pair it with width: "auto" to size from the height instead.
  • Avoid: Place it in a shrink-to-fit parent such as inline-flex, width: fit-content or a floated box. It contributes no intrinsic width there and collapses to zero.

Theming API

{
  "targets": [
    {
      "className": "astryx-aspect-ratio",
      "visualProps": [
        "shape"
      ]
    }
  ]
}

Anatomy

  • Ratio box: The outer element that holds the aspect ratio and clips overflow. Carries the astryx-aspect-ratio theme target, and the elliptical clip when shape is ellipse.
  • Content slot: A wrapper that fills the ratio box and positions the child. With fit set it also sizes the child; without it the child styles itself.

Examples

  • Aspect Ratio: Three aspect ratio containers at equal height (1:1, 4:3, and 16:9), each showing an image with its ratio labeled below.
  • AspectRatio — Circle Image: Circular container via shape="ellipse" with ratio={1}, ideal for avatars and profile images.
  • AspectRatio — Image Gallery: Grid of images with consistent 4:3 aspect ratios.
  • AspectRatio — Square Image: 1:1 square aspect ratio, ideal for avatars and Instagram-style images.
  • AspectRatio — 16:9 Widescreen Image: 16:9 widescreen aspect ratio wrapping an image.
  • AspectRatio — Loading Skeleton: Aspect ratio container with a skeleton loading placeholder.