Container queries
Reflow layouts based on their slot width, not the viewport — the right tool for reusable components in variable-width contexts.
Narrow slot (max-w-xs)
Anna Whitfield
Relationship manager
Next review · 14 Aug 2026
anna@whitfieldwealth.co.uk
Wide slot (full width)
Anna Whitfield
Relationship manager
Next review · 14 Aug 2026
anna@whitfieldwealth.co.uk
Usage
import { Container, Flex, Stack } from "@reva/ui";Container queries let a component reflow based on the width of its own container, not the viewport. Use them for reusable components that land in variable-width slots — a card in a sidebar vs. a main column, a widget in both a narrow panel and a wide grid cell.
The rule is simple: @* keys target the container; *: keys target the viewport.
| Key | Resolves against | Example |
|---|---|---|
md: | Viewport (--breakpoint-md = 64rem / 1024px) | { default: "column", md: "row" } |
@md | Container (--container-md = 32rem / 512px) | { default: "column", "@md": "row" } |
The --container-* scale and --breakpoint-* scale are different sizes and different reference boxes — never assume they match.
Opening a container context
Flex, Stack, and Grid emit @* classes, but they need a containment context to resolve against. Add containerType="inline-size" to the nearest Container ancestor:
<Container containerType="inline-size">
{/* @md variants inside here now resolve against this element's width */}
<Flex direction={{ default: "column", "@md": "row" }} gap={4}>
<div>Left</div>
<div>Right</div>
</Flex>
</Container>containerType is opt-in — it has a layout cost (the browser must isolate the subtree for measurement), so only add it where reflow is needed.
Naming containers
If you nest multiple containment contexts and need to target a specific ancestor, pass containerName alongside containerType:
<Container containerType="inline-size" containerName="card">
{/* @md/card: targets the "card" container specifically */}
</Container>Examples
Narrow vs wide reflow
The two instances below render the same card component — same markup, same props. Each is wrapped in a <Container containerType="inline-size"> of a different width. The Flex direction={{ default: "column", "@md": "row" }} prop makes the inner layout stack vertically in the narrow slot and shift to a row in the wide slot.
Resize the browser window — neither instance changes. The reflow responds to container width, not viewport width.
Narrow slot (max-w-xs)
Anna Whitfield
Relationship manager
Next review · 14 Aug 2026
anna@whitfieldwealth.co.uk
Wide slot (full width)
Anna Whitfield
Relationship manager
Next review · 14 Aug 2026
anna@whitfieldwealth.co.uk
When to use container queries vs media queries
Reach for @* (container) when the component is reusable and drops into slots of unknown width — cards in a grid, widgets in a sidebar, items in a dynamic layout.
Reach for *: (viewport) when the concern is the page shell — the app frame, global nav collapse, page gutters, breakpoint-aware padding on Container.
A common pattern: the shell uses viewport media queries to define column widths; components inside those columns use container queries to reflow within their allocated slot.
Props
Container query support is built into Flex, Stack, and Grid via their responsive props, and into Container via the containerType/containerName props.
Container
| Prop | Type | Default | Description |
|---|---|---|---|
containerType | "inline-size" | "size" | "normal" | — | Opens a CSS container-query context. "inline-size" covers the common case (horizontal reflow). |
containerName | string | — | Names the context (@container/{name}) for targeted @md/{name}: variants. |
Flex, Stack, Grid — responsive props
Pass an object with @* keys to use container-relative values:
// Viewport — switches at viewport ≥ md (1024px)
<Flex direction={{ default: "column", md: "row" }} />
// Container — switches when the container ≥ @md (512px)
<Flex direction={{ default: "column", "@md": "row" }} />
// Mixed — rare; stack at viewport sm, go row when container is @lg
<Flex direction={{ default: "column", sm: "column", "@lg": "row" }} />Available container rungs: @sm (24rem) · @md (32rem) · @lg (48rem) · @xl (64rem) · @2xl (80rem) · @3xl (96rem).