design system
Adaptive Card Component
This card reflows on its container, not the viewport. Resize the wrapper to watch vertical → horizontal → expanded.
views
12.4k
updated
2 days ago
@container) and
frontend/foundations: flexbox
(the flex-row / flex-col the card flips between).
Media queries are page-driven: one component looks identical everywhere at the same viewport size. Container queries are component-driven: the same markup reflows based on the space its parent gives it. Drop one card into a narrow sidebar, a wide grid cell, or a modal — it adapts to each placement automatically, with zero JavaScript.
| dimension | media query (page-driven) | container query (component-driven) |
|---|---|---|
| signal | viewport width (md:) |
container width (@md:) |
| same component, different slots | ❌ identical everywhere at a given viewport | ✅ reflows per slot — sidebar card ≠ hero card |
| trigger source | browser window resize only | sidebar toggle, grid reflow, modal open — any layout change |
| reusability | coupled to page layout | self-contained, portable across pages & apps |
| JS needed? | no — but can't react to placement | no — pure CSS, reacts to its own box |
Drag the slider to resize the wrapper, not the browser. The card
uses flex-col by default, @md:flex-row at
≥448px, and adds a larger image + 2-column meta at @2xl
(≥672px). The viewport never changes — only the container does.
design system
This card reflows on its container, not the viewport. Resize the wrapper to watch vertical → horizontal → expanded.
views
12.4k
updated
2 days ago
container-type: — · flex-direction: — · state: —
The identical card markup below lives in three fixed-width containers — a sidebar (260px), a grid cell (520px), and a hero slot (720px). All three render at the same viewport size; only their containers differ. This is the design-system payoff: one component, every context.
card
Stacks vertically in a narrow column.
card
Image goes left, text right — horizontal layout.
card
Larger image, room for richer content.
| pattern | trigger | container-query mechanic |
|---|---|---|
| adaptive card | card placed in slots of varying width | flex-col @md:flex-row + image/text size at @2xl |
| sidebar toggle | JS collapses a sidebar → main column widens | main is @container; children reflow with no media query |
| component-library card | same card dropped in grid / sidebar / modal | card owns an @container wrapper; adapts to each host |
| data table → cards | narrow container can't fit columns | @max-lg:hidden table, card list shown below @lg |
| nav: inline → overflow | toolbar items exceed container width | @max-md:hidden extras + a "more" menu under @md |
Sidebar toggle & component-library card are not interactive here — they're illustrated with code in the guide (.md). The key point: a layout change driven by JS state (collapsing a sidebar) changes the container size, which fires the container query — no media query or resize listener is involved.
Verified values (Tailwind v4, 2026-06). The demo switches at
@md = 28rem (448px) and expands at @2xl = 42rem (672px).
| variant | min-width | adaptive-card role |
|---|---|---|
@sm: | 24rem (384px) | — |
@md: | 28rem (448px) | flip flex-col → flex-row |
@lg: | 32rem (512px) | — |
@xl: | 36rem (576px) | — |
@2xl: | 42rem (672px) | larger image + 2-col meta |
@3xl: | 48rem (768px) | — |
@4xl: | 56rem (896px) | — |
| intent | pattern |
|---|---|
| make a slot queryable | <div class="@container"> |
| flip layout by container | flex-col @md:flex-row |
| size per state | w-full @md:w-36 @2xl:w-52 |
| range (below a width) | @max-md:flex-col |
| target a specific container | @container/main + @md/main: |
| arbitrary container size | @min-[475px]:flex-row |