Media Queries vs Container Queries in CSS
Media queries respond to the viewport size; container queries respond to a component's own container. When to reach for each in a responsive layout.
A media query applies styles based on the size of the browser viewport; a container query applies styles based on the size of a specific containing element. Both let you write responsive CSS, but they answer different questions — “how big is the screen?” versus “how much space does this component actually have?” — and that difference determines which one you should reach for.
What media queries actually measure
Media queries have been the default tool for responsive design since CSS3, and they work off a single global signal: the viewport.
@media (min-width: 768px) {
.card { flex-direction: row; }
}
This rule fires once the browser window is at least 768px wide, everywhere on the page. That’s fine when a layout genuinely depends on screen size — a page-level grid that goes from one column to three, or a navigation bar that collapses into a hamburger menu below a certain width. See CSS media queries explained for the full syntax, including range syntax and the newer @media (width >= 768px) form.
The limitation shows up with reusable components. A card component might render at full viewport width in a single-column layout, or squeezed into a narrow sidebar next to other content — the viewport is the same in both cases, but the space available to the card is completely different. A media query can’t see that; it only knows about the window.
What container queries measure instead
A container query asks a narrower, more useful question: how big is this specific container, regardless of the viewport? First, mark an element as a query container:
.card-wrapper {
container-type: inline-size;
container-name: card;
}
Then style a descendant based on that container’s size, not the window’s:
@container card (min-width: 400px) {
.card { flex-direction: row; }
}
Now the card lays out horizontally whenever its own wrapper is at least 400px wide — whether that wrapper sits in a full-width main column or a narrow sidebar. The component becomes responsive to its context rather than to the page as a whole, which is exactly what you want for anything meant to be dropped into different layouts: a card, a widget, a piece of a design system.
Media queries vs container queries
| Media queries | Container queries | |
|---|---|---|
| Responds to | Viewport (or device) size | A specific container’s size |
| Best for | Page-level layout, global breakpoints | Reusable components, design systems |
| Setup | Works immediately, no markup changes | Requires container-type on an ancestor |
| Also handles | Orientation, color scheme, reduced motion, print | Only size and (in newer browsers) style queries |
| Nesting | Independent of DOM structure | Needs a container ancestor in the DOM |
Media queries remain the right tool for anything that isn’t about an individual component’s box: prefers-color-scheme for dark mode, prefers-reduced-motion for animation, orientation for portrait versus landscape, and print stylesheets all live in the media-query world — container queries don’t cover any of that. And when it comes to typography that should scale smoothly rather than jump at breakpoints, neither replaces clamp()-based fluid sizing, which is a separate technique for a separate problem.
Using them together
These aren’t competing techniques — most modern responsive layouts use both. A common pattern: media queries define the page-level grid (how many columns, how the overall structure changes at a few global breakpoints), and container queries handle how each component reflows within whatever column or panel it lands in.
/* Page-level: media query decides the overall grid */
@media (min-width: 1024px) {
.layout { grid-template-columns: 1fr 3fr; }
}
/* Component-level: container query decides the card's own layout */
@container card (min-width: 400px) {
.card { flex-direction: row; }
}
This pairing avoids a real problem with container-query-only designs: without any media queries, a component has to be tested at every possible container width it might ever encounter, since it has no idea what page it’s on. Media queries still anchor the big picture; container queries make the details of each piece independent of where it ends up.
Browser support and fallbacks
Container queries are supported in all current major browsers, but if you need to support noticeably older browsers, treat container-query styles as progressive enhancement: define a reasonable default layout outside the @container block, then refine it inside the query. A card that’s already usable at its default size, and merely improves when the container is wide enough, degrades gracefully rather than breaking.
The takeaway
Media queries answer “how big is the screen,” which makes them the right tool for page-level structure and things like color scheme and motion preferences. Container queries answer “how much space does this component have,” which makes them the right tool for components that need to work correctly no matter where they’re dropped in a layout. Use media queries to shape the page and container queries to make each piece within it truly reusable — most real layouts need both.
Tagged
Keep reading
Takina · · 4 min read What Is CSS Subgrid? Nested Grid Alignment Explained
CSS subgrid lets a nested grid item inherit its parent's track sizing, so children can align to the same columns or rows across unrelated containers.
Takina · · 4 min read CSS field-sizing Property Explained
The CSS field-sizing property lets form controls like textareas grow to fit their content automatically, without JavaScript resize listeners.
Takina · · 3 min read CSS Scrollbar Styling: scrollbar-color and scrollbar-width
CSS now styles scrollbars natively with scrollbar-color and scrollbar-width, replacing years of vendor-prefixed hacks. Here's how they work.