Responsive Strategy & Container Queries
In one line
Media queries ask how wide the window is, container queries ask how wide the component's parent is — and in a component-based codebase the second question is nearly always the one you meant.
What it is
The breakpoint model assumed pages. A component does not know whether it is in a full-width hero, a two-thirds column, or a 300px sidebar, and viewport width tells it nothing about the space it actually has. That mismatch is why design systems accumulate variant="compact" props: a manual, error-prone way of passing down information the component could measure itself.
Container queries fix it directly. Mark an ancestor with container-type: inline-size, then write @container (min-width: 400px) { ... }. The same card component lays out as a row in a wide slot and a column in a narrow one, with no prop and no knowledge of the page. Container query units — cqi, cqw, cqb — size relative to the container rather than the viewport. Named containers (container-name) let a component query a specific ancestor when several are nested.
Intrinsic techniques remove queries altogether, and they are usually the better first move. clamp(min, preferred, max) gives fluid typography and spacing in one declaration. min() and max() express "whichever is smaller" without a breakpoint. repeat(auto-fit, minmax(200px, 1fr)) wraps a grid by available space. flex-wrap handles a row that becomes several. Each of these describes intent rather than enumerating widths, which means it keeps working at sizes nobody tested.
Media queries retain a real role — just a narrower one. They are right for genuinely page-level decisions and, importantly, for user preference queries: prefers-reduced-motion, prefers-color-scheme, prefers-contrast, and prefers-reduced-transparency are media queries, and respecting them is an accessibility requirement rather than a nicety.
Two practical cautions. container-type: inline-size applies size containment on the inline axis, so the container no longer sizes to its contents in that direction — an element that collapses after adding it is showing you that, not a bug. And a container cannot query itself; the query applies to descendants, so the component needs a wrapper.
Why it matters
Component libraries are the dominant way UI is built, and container queries are the first mechanism that makes a component genuinely self-contained — it is a real architectural shift, not a syntax addition.
Interviewers ask about it as a currency check, and the strong answer includes the intrinsic techniques that avoid queries entirely.
Key points
- Viewport width does not describe the space a component occupies; container queries do.
container-type: inline-sizeplus@containerlets one component adapt to any slot without props.cqi/cqwunits size relative to the container; named containers disambiguate nesting.- Prefer intrinsic techniques first —
clamp(),min(),max(),auto-fitgrids,flex-wrap. - Media queries remain correct for page-level decisions and for user preference queries.
- Always honour
prefers-reduced-motionandprefers-color-scheme. container-typeapplies size containment, and a container cannot query itself — wrap it.