container query variants

[check: …]
📖 Pair this live explorer with the companion guide (.md) — this page is the rendered ground truth for the full @-variant range. ↗ Builds on container_basics (the @container + container-type foundation this extends).

the @ variant scale — 13 container breakpoints

Every container variant maps to a --container-* theme token. @md: fires when the container's inline-size is --container-md (28rem / 448px). These are independent from viewport breakpoints (sm:, md: use --breakpoint-*) — same names, different namespace, different trigger (container vs window).

varianttheme tokendefaultpx (root 16)fires when container…
@3xs:--container-3xs16rem256px≥ 256px
@2xs:--container-2xs18rem288px≥ 288px
@xs:--container-xs20rem320px≥ 320px
@sm:--container-sm24rem384px≥ 384px
@md:--container-md28rem448px≥ 448px
@lg:--container-lg32rem512px≥ 512px
@xl:--container-xl36rem576px≥ 576px
@2xl:--container-2xl42rem672px≥ 672px
@3xl:--container-3xl48rem768px≥ 768px
@4xl:--container-4xl56rem896px≥ 896px
@5xl:--container-5xl64rem1024px≥ 1024px
@6xl:--container-6xl72rem1152px≥ 1152px
@7xl:--container-7xl80rem1280px≥ 1280px

Range variants: prefix max-@max-sm: fires when the container is < 24rem (384px). Arbitrary: @min-[400px]: / @max-[400px]: for one-off thresholds. Stacking: @sm:flex-row @lg:gap-8 — both apply, larger wins.

1 · resize the container — watch every @ variant activate

Drag the slider to change the container width. The grid below switches column count at @3xs/@xs/@sm/@md/@lg; the chip bar reads out all 13 min-width variants live (✅ = active, ❌ = inactive). The values come straight from getComputedStyle() on invisible probe elements — what you see is the browser's container-query engine, not JS math.

450px
1
col
2
col
3
col
4
col
5
col
6
col
stacking → @sm:flex-row @lg:gap-6
container-type: — · grid-template-columns: —
@3xs @2xs @xs @sm @md @lg @xl @2xl @3xl @4xl @5xl @6xl @7xl

2 · beyond min-width: ranges, arbitrary values, stacking

patternsyntaxfires when container…generated CSS (sketch)
min-width (default) @md:grid-cols-2 ≥ 28rem @container (width >= 28rem)
max-width range @max-md:hidden < 28rem @container (width < 28rem)
between two breakpoints @sm:block @max-lg:hidden 24rem ≤ w < 32rem min & max queries ANDed
arbitrary min @min-[400px]:flex ≥ 400px @container (min-width: 400px)
arbitrary max @max-[400px]:hidden < 400px @container (max-width: 400px)
stacked variants @sm:flex-row @lg:gap-8 two independent rules larger breakpoint wins on conflict (ascending source order)
override threshold @theme { --container-md: 20rem } now @md: = 20rem redefines the token the variant reads

Why @max-sm: = < 24rem and not ? Tailwind emits a strict width < comparison so min- and max- variants never overlap at the exact boundary — no double-application at 384.000px.

intent → variant

intentpatternwhy
respond to container width class="@container" → @md:grid-cols-2 parent needs @container; child reads --container-md
only-when-narrow @max-sm:hidden range query: hides below 24rem (sidebar widget compact mode)
one-off threshold @min-[400px]:flex-row arbitrary value — no theme edit needed
progressive grid grid-cols-1 @sm:grid-cols-2 @lg:grid-cols-3 @2xl:grid-cols-4 each variant widens the grid as space grows
combine two breakpoints @sm:flex-row @lg:gap-8 stack — both rules apply; ascending order resolves conflicts
customize a breakpoint @theme { --container-md: 20rem; } shifts every @md: site app-wide