container queries basics

[check: …]
📖 Pair this live Tailwind demo with the companion guide (.md) — this page is the rendered ground truth. ↗ Builds on frontend/tailwind: responsive variants (viewport breakpoints — container queries are the component-level evolution).

Media queries → container queries: the evolution

Media queries ask "how wide is the viewport?". Container queries ask "how wide is my container?". A card in a narrow sidebar should stack vertically; the same card in a full-width area should spread horizontally. Container queries make this possible without JavaScript — the component responds to its own available space, not the browser window.

conceptmedia querycontainer query
what it asks "how wide is the @media viewport?" "how wide is my @container parent?"
breakpoint trigger browser window resize container element resize (layout change, sidebar toggle, grid reflow)
component reusability ❌ same component looks same everywhere at same viewport size ✅ same component adapts to WHERE it's placed
Tailwind v4 syntax md:grid-cols-2 (viewport ≥ 768px) @md:grid-cols-2 (container ≥ 288px)
setup nothing — viewport is always available parent needs class="@container" (sets container-type: inline-size)

1 · resize the container — watch the card adapt

Drag the slider to change the container width. The card inside uses @container query variants: at narrow widths it stacks vertically (1 column); at wider widths it spreads horizontally (2 columns). This is component-driven responsive design — no viewport resize needed.

400px

left cell

Adapts to container, not viewport.

right cell

Visible when container ≥ @md (288px).

container-type: — · grid-template-columns: —

2 · container breakpoints (Tailwind v4 defaults)

variantcontainer min-widthtypical use
@sm:24rem (384px)small containers — sidebar widgets
@md:18rem (288px)default — cards, panels
@lg:32rem (512px)medium containers — main content
@xl:48rem (768px)wide containers — full-width sections
@2xl:64rem (1024px)very wide — dashboards
@3xl:80rem (1280px)extra wide
@4xl:96rem (1536px)maximum width

intent → pattern

intentpatternwhy
make a parent queryable <div class="@container"> sets container-type: inline-size — children can use @ variants
child responds to container width @md:grid-cols-2 when container ≥ 288px, switch to 2 columns
range query (max-width) @max-md:hidden hide when container < 288px (v4 supports @max- variants)
named container class="@container/sidebar" child uses @sm/sidebar: to target a specific container
override container breakpoints @theme { --breakpoint-md: 20rem; } customize the @md: threshold in your theme