"Media queries ask 'how big is the viewport?'. Container queries ask 'how big is *this* parent?'. That single shift makes components actually reusable."
The Problem Container Queries Solve
You build a beautiful card component. It looks great on the homepage at full width. You drop the same card into a 280px sidebar — and the image is too big, the text wraps weirdly, the CTA button doesn't fit. The card is broken not because of the viewport, but because of its container.
Before container queries, the only fix was to write "sidebar variant" CSS or rely on viewport media queries (which fail when the same viewport hosts the card in two different contexts). Container queries let the component ask "how wide am I being rendered?" and adapt — regardless of what's around it.
The Two-Step Pattern
Container queries always involve two pieces:
- Declare a containment context on the parent that should be queried. Use
container-type. - Query that container from inside its descendants using
@container.
Step 1: container-type
container-type: inline-size— query the container's inline size (width in LTR). Most common. The container's size is determined by its own width; descendants can query that width.container-type: size— query both inline and block (width AND height). The container's size becomes self-determining, which means it doesn't size to its children — be careful, this can collapse the container.container-type: normal— not a container, no queries possible (default).
Almost always use inline-size. size is for specialized cases (containers with known fixed heights).
Step 2: @container
Inside descendants, query the nearest containment context:
Naming Containers For Clarity
When components nest containers, naming them avoids ambiguity. Otherwise, @container queries the nearest ancestor with a container type:
Container Query Units: cqw, cqh, cqi, cqb
Just as vw and vh are viewport units, container query units measure relative to the container:
cqw— 1% of container's width.cqh— 1% of container's height.cqi— 1% of container's inline size (= cqw in LTR).cqb— 1% of container's block size (= cqh in horizontal writing-mode).cqmin,cqmax— min/max of cqi and cqb.
These let you size things relative to the container, not the viewport — making components truly self-contained.
The Catch: Container Type Changes Layout Behavior
container-type: inline-size establishes a containment context, which affects how layout interacts with the container. Specifically, the container becomes the containing block for absolutely positioned descendants, and certain layout optimizations apply. Usually invisible; occasionally you'll see a subtle layout change. The fix is to apply container-type on a wrapper that doesn't otherwise affect layout.
Browser Support
Container queries are baseline 2023, supported in all major browsers (Chrome, Edge, Safari, Firefox). The cq* units are also baseline. There's no need to polyfill in 2026.
When To Use Container Queries vs Media Queries
- Media queries: page-level structure. "At desktop width, show the sidebar." Site-wide patterns. User preferences.
- Container queries: component-level adaptation. "Card switches from stacked to horizontal layout when its container is > 400px."
Most real apps use both. The page shell responds to the viewport (media queries); the cards inside respond to their containers (container queries).