Container Query vs Media Query — When to Use Which
Decide between @container and @media in real scenarios with concrete examples — page layout vs component layout, viewport state vs container state, and the cost of each.
Detailed Explanation
Beyond the Definition: When to Reach for Each
The textbook answer ("media queries respond to the viewport, container queries to the parent") is correct but not actionable. Here's the decision framework with examples.
Use @media When…
- The viewport itself matters. Print stylesheets, dark mode preference, reduced motion, hover capability — these are properties of the device or session, not of any container.
- You're styling page chrome. The header, footer, top-level nav, and main grid live at the page level. Their breakpoints align naturally with viewport widths.
- You need broad browser support.
@mediaworks everywhere, including ancient browsers that container queries can't reach.
@media (prefers-color-scheme: dark) { /* theme */ }
@media (min-width: 1024px) { .page { display: grid; grid-template-columns: 240px 1fr; } }
@media print { .nav { display: none; } }
Use @container When…
- The component lives in many sizes. A card might appear at 320px (sidebar), 480px (column), 1200px (banner). One
@containerrule handles all three. - You're shipping reusable components. Design-system primitives must work in any layout. Container queries are the only honest way to deliver true context-independence.
- The component sits below a flexible layout. When a sidebar collapses, a main column grows. Container queries react to that growth automatically; media queries can't.
.card-host { container-type: inline-size; }
@container (min-width: 400px) {
.card { display: grid; grid-template-columns: 200px 1fr; }
}
Use Both Together
/* Page layout */
@media (min-width: 1024px) {
.page {
display: grid;
grid-template-columns: 280px 1fr;
}
}
/* Card behavior inside the page */
.card-host { container-type: inline-size; }
@container (min-width: 480px) {
.card { display: grid; grid-template-columns: 200px 1fr; }
}
When the sidebar collapses (because the user closed it), the main column widens, and cards that were previously narrow may now flip to horizontal. Media queries handle the page; container queries handle the cards.
Cost Comparison
| Aspect | @media | @container |
|---|---|---|
| Browser cost | Free (always evaluated) | Requires layout pass on host |
| JS cost | None | None |
| Browser support | Universal | Modern (2022+) |
| Setup | Nothing | container-type on parent |
| Reusability across contexts | Poor | Excellent |
Migration Strategy
Don't migrate everything. Move reusable components to container queries first. Leave page chrome on media queries. Most projects end up using both, comfortably.
Use Case
Reference this guide when choosing between @media and @container for a specific component or page region. Use @media for page chrome and device state; use @container for reusable components.