The 94% Support, 41% Adoption Problem
CSS container queries have roughly 94% browser support. Yet according to the State of CSS survey, only 41.4% of developers actually use them — despite 86% being aware they exist. That gap isn't a tooling problem. It's a mental model problem.
The reason is simple: at first glance, @container looks exactly like @media. Same syntax shape, same (min-width: ...) pattern. So developers assume they behave the same way, copy their media query habits over, and end up with components that break in sidebars, grid cells, and any context where the viewport is a useless proxy for available space.
This article is about fixing that mental model — not by adding container queries everywhere, but by understanding what question each query type is actually asking the browser. For a deeper look at the original argument, see the source material on Smashing Magazine.
Media Queries Look Outward. Container Queries Look Inward.
When you write @media (min-width: 1024px), you're asking the browser one thing: how wide is the screen right now? That's it. The viewport is a proxy for everything responsive, and it works beautifully — until it doesn't.
/* Media query: viewport-driven */
@media (min-width: 1024px) {
.card {
display: flex;
}
}
Drop that .card into a 300px grid cell on a 1920px desktop and the media query still fires. The card gets display: flex with 300px of space and deforms.
Container queries ask a different question: how much inline space do I have right here, in this specific slot?
/* Container query: component-driven */
.card-wrapper {
container-name: card;
container-type: inline-size;
}
@container card (min-width: 450px) {
.card {
display: flex;
flex-direction: row;
}
}
The card now responds to its wrapper, not the viewport. Move it into a sidebar, a modal, or a full-width hero — it adapts correctly in every context.

Macro Layout vs. Micro Layout: The Mental Model That Fixes Everything
Stop thinking of container queries as "media queries 2.0." Think of them as a different layer of responsive design.
| Layer | Tool | Question | Examples |
|---|---|---|---|
| Macro | @media | How big is the viewport? | Page grid, header, footer, prefers-color-scheme, touch detection |
| Micro | @container | How much space do I have here? | Cards, widgets, forms, nav items, embedded components |
An element shouldn't become "tablet-sized" because the viewport crossed 768px. It should switch layout when it has enough space — whether that happens on mobile or inside a desktop sidebar. There are over 2,300 unique viewport sizes in the wild. You cannot enumerate them. You can, however, define what "enough space" means for a component.
Fluid Typography, Done Right
Viewport units (vw) tie type to the screen. Container units (cqi, cqw, cqb) tie type to the component.
/* Wrong: scales with viewport, breaks in sidebars */
.card-title {
font-size: clamp(100%, 1rem + 2vw, 24px);
}
/* Right: scales with the component's container */
.card-title {
font-size: clamp(1rem, .5rem + 3cqi, 2rem);
}
The Flexbox Wrap Trick
CSS has no :wrapped pseudo-class. But you can detect flex wrapping with container queries by letting flex items expand when they wrap:
.flex-layout {
display: flex;
flex-wrap: wrap;
}
.flex-item {
container-type: inline-size;
flex: 1 1 390px; /* Grow to fill, wrap at 390px */
}
.card {
display: flex;
flex-direction: column;
background: #f4f4f4;
}
/* Fires when a wrapped item stretches to fill the row */
@container (min-width: 600px) {
.card {
flex-direction: row;
align-items: center;
background: #e2f0d9;
}
}
When items wrap, flex-grow stretches them, the container query detects the size change, and styles apply — no ResizeObserver required.

Three Gotchas That Break Real Implementations
1. A Container Cannot Query Itself
This is the #1 mistake. You need a wrapper.
/* DOES NOT WORK — infinite loop */
.card {
container-name: card;
container-type: inline-size;
}
@container card (min-width: 400px) {
.card { display: flex; }
}
/* WORKS — wrapper is the container */
.cards {
container-name: cards;
container-type: inline-size;
}
@container cards (min-width: 400px) {
.card { display: flex; }
}
Media queries don't care — the viewport is always available. Container queries require an explicit parent-child relationship.
2. container-type: size Can Collapse Your Layout
/* Collapses to 0px height if no explicit height is set */
.hero-banner {
container-type: size;
}
The browser computes container dimensions without looking at children. No explicit height, min-height, or aspect-ratio means 0px. Default to inline-size unless you genuinely need block-size queries.
3. Custom Properties Are Not Queryable
:root { --breakpoint-lg: 1600px; }
/* DOES NOT WORK */
@container (min-width: var(--breakpoint-lg)) { /* ... */ }
Custom properties cascade, and a container query that reads one could, in theory, mutate it — creating a circular dependency. Use literal values in container queries.
When to Reach for Which
- Container queries: component appears in multiple layout contexts (grid + sidebar + modal).
- Media queries: component is page-level (main nav, footer, page shell).
If you're building out a broader system of resilient, context-aware UI, it's worth pairing this with architectural thinking at the infrastructure layer — for example, the design principles behind Azure IaaS resiliency apply the same "adapt to context" logic at the platform level.

The Takeaway
Container queries aren't a replacement for media queries — they're a second axis of responsiveness. Media queries handle the macro layout; container queries handle the micro layout. Confusing the two is why so many implementations feel fragile.
The mental shift is small but consequential: stop asking "how big is the screen?" and start asking "how much space does this component actually have?" Once that clicks, the code writes itself.
Limitations Worth Acknowledging
- Container queries still require an extra wrapper element in most cases, which can complicate simple markup.
- Style queries (
@container style(...)) remain experimental and shouldn't be relied on in production yet. - Debugging container queries in DevTools is improving but still less mature than media query tooling.
Next Steps
- Audit your component library for any component that renders in more than one layout context. Those are your container query candidates.
- Replace
vw-based fluid typography withcqiinside those components. - Keep
@mediafor page-level concerns — don't over-rotate.
If you're interested in how similar "context-aware adaptation" principles play out in experimentation and measurement systems, the surrogate outcome framework for LLM-driven A/B testing is a worthwhile parallel read.
Source: Stop Treating CSS Container Queries Like Traditional Media Queries