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.

Container vs Media

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. @media works 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 @container rule 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.

Try It — CSS Container Query Builder

Open full tool