Skip to content
Cynosurev0.5.0
SearchStorybookGitHubnpmColour mode: System. Switch to Light

Components / Structure

AspectRatio

A box that keeps a width-to-height ratio at any width, for an image, a video, a map, a chart or an embed. For a picture that also needs a loading placeholder and an error fallback, use Image instead.

Default

When to useLink to "When to use"

  • Media that arrives late: reserve the space for a video, an iframe or a map so the page does not jump when it loads.
  • Content with no size of its own: a chart or a canvas that draws into whatever box it is given.
  • Even grids: thumbnails or tiles that must share one shape whatever is inside them.

Use something else when:

  • it is a picture: Image with ratio, which uses this box and adds loading and error states
  • the content should set its own height: a plain element, or Card for a framed surface
  • you are waiting for content and want a placeholder: Skeleton

UsageLink to "Usage"

tsx
Copy
import { AspectRatio } from "@arshad-shah/cynosure";

<AspectRatio>
  <video src="/intro.mp4" controls />
</AspectRatio>

<AspectRatio ratio="4/3" radius="card">
  <Map />
</AspectRatio>

<AspectRatio ratio={1} style={{ inlineSize: 160 }}>
  <Chart />
</AspectRatio>

ratio is the width divided by the height: a number (16 / 9, 1) or a CSS ratio ("4/3"). The default is 16 / 9.

CornersLink to "Corners"

radius rounds the corners from the radius tokens and clips the content to them. The default is square.

Radius follows the tokens

PropsLink to "Props"

Every prop of AspectRatio
PropWhat it doesTypeDefault
ratio
Width divided by height: a number (16 / 9, 1) or a CSS ratio ("4/3"). A number that is not above zero uses the default. Default 16 / 9.string | number`16 / 9`
radius
Rounds the corners from the radius tokens; the content is clipped to them. Default "none".AspectRatioRadius"none"
className
Added to the root element, for layout.string
style
Layout only (width, margin, placement). The height always follows from the width.CSSProperties
children
What fills the box. Each child is stretched to it; an image, video or canvas covers it (object-fit: cover).ReactNode

Generated from the type definitions in @arshad-shah/cynosure 0.5.0.

Behaviour and accessibilityLink to "Behaviour and accessibility"

Behaviour and accessibility, table 1
SituationResult
The container gets wider or narrowerThe height follows in CSS; nothing is measured and nothing re-renders
style asks for more width than the container hasIt stops at the container's width, and the height follows that
It sits in a flex rowIt keeps the full width instead of collapsing
A child is taller than the boxThe child is clipped; the box keeps its ratio
ratio is 0, negative, NaN or infiniteThe default 16 / 9 is used
  • Children: every direct child is stretched over the whole box, so give it one child. What is inside that child lays out as usual.
  • Images and videos: a direct child that is an image, a video or a canvas covers the box (object-fit: cover) instead of being squashed. object-fit does nothing to other elements, so a div or an iframe is only stretched. For contain, set object-fit on the child.
  • No look of its own: no fill and no border, and text styles are inherited from where it sits.
  • Semantics: a div with no role. Name the content inside it (an alt, an iframe's label).
  • Right-to-left: nothing changes.

TouchLink to "Touch"

Nothing in AspectRatio can be pressed. Controls inside it bring their own hit areas.

ThemingLink to "Theming"

Tokens: --cy-aspect-ratio-radius (the corner radius of every AspectRatio, whatever its radius prop says).

css
Copy
.gallery {
  --cy-aspect-ratio-radius: 6px;
}

className and style are for layout only (width, margin, placement).

Image · Skeleton · Card · Grid

These examples run Cynosure 0.5.0 (commit 50ce30b), the version on npm.

Getting started
Theming
Icons
Accessibility
Code editors and highlighters
Using Cynosure without React
Build-tool adapters
Components
Accordion
AppShell
AspectRatio
Breadcrumbs
Calendar
Card
Container
Disclosure
Divider
DocumentViewport
Grid
Inline
PageHeader
PanZoomCanvas
ScrollArea
SideNav
SortableList
SplitPane
Stack
StatusBar
Tabs
TitleBar
Toolbar
Tree
VirtualList
ZoomControls
Announcer
Avatar
Badge
CodeBlock
DescriptionList
EmptyState
ErrorBoundary
Field
Heading
IconTile
Image
Kbd
List
LoadingDots
Notice
ProgressBar
Prose
Skeleton
Stat
Steps
Table
Text
Button
Checkbox
Checklist
ColorField
ColorSwatches
Combobox
CompareSlider
CopyButton
DateField
FileDrop
IconButton
KeyValueEditor
Link
NumberField
Pagination
PathField
RadioGroup
SearchField
SegmentedControl
Select
SelectionFrame
SignaturePad
Slider
Switch
TagInput
TextArea
TextField
ThemeToggle
TimeField
ButtonBase
ChoiceBase
DialogBase
FileInputBase
HiddenValue
Icon
InputBase
LinkBase
LiveRegion
TextAreaBase
ChatMessage
Choice
DataGrid
DeviceFrame
HighlightedText
HotkeyField
ListRow
OptionList
OverlayFrame
QRCode
RowActions
Section
SiteFooter
SiteHeader
SkipLink
SortButton
VisuallyHidden
CommandPalette
ContextMenu
Dialog
FloatingToolbar
HoverCard
Menu
Menubar
Popover
ProgressOverlay
Sheet
Toast
Tooltip
Changelog