📦 CSS Container Queries: The End of Media Query Hell — A Practical Guide with Real Examples

📅 2026-06-10 ⏱️ 4 min read 🏷️ Web Technology

For over a decade, responsive web design meant one thing: @media queries. But media queries respond to the viewport — not the component. If a card component is in a 1200px-wide main column it needs one layout; in a 300px sidebar it needs another. With media queries, you write separate breakpoints for every context where the component appears. With Container Queries (stable in all major browsers since early 2023), the component responds to its own container. This changes component architecture fundamentally.

The Problem with Media Queries (A Real Example)

Consider a product card component used in three places: a 3-column grid on desktop (each card ~380px), a 2-column grid on tablet (each card ~340px), and a sidebar widget (200px). With media queries, you'd write:

/* Card in main content */
@media (min-width: 768px) { .product-card { /* tablet layout */ } }
@media (min-width: 1024px) { .product-card { /* desktop layout */ } }

/* Card in sidebar — completely separate rules */
.sidebar .product-card { /* always compact */ }

This couples the component to the page layout. Move the component to a new context, and you need new breakpoints. The CSS grows quadratically with the number of layout contexts × components.

The Container Query Solution

With Container Queries, the component defines its own breakpoints based on its container's width:

/* Define a containment context on the parent */
.card-wrapper {
  container-type: inline-size;
  container-name: card;
}

/* The component responds to its OWN container */
@container card (min-width: 350px) {
  .product-card {
    display: grid;
    grid-template-columns: 120px 1fr;
  }
}

@container card (min-width: 500px) {
  .product-card {
    grid-template-columns: 200px 1fr;
  }
}

The same component, placed in a 200px sidebar or a 600px main column, automatically applies the correct layout — no context-specific CSS required. The component is truly self-contained. This is the biggest advance in CSS layout since Flexbox (2012) and Grid (2017).

Container Query Units: The Other Game-Changer

Alongside @container, CSS now has container query length units: cqw (1% of container width), cqh (1% of container height), cqi (inline), cqb (block), cqmin, cqmax. These replace viewport units (vw, vh) inside components:

.card-title {
  /* Before: font-size tied to viewport — breaks in narrow containers */
  font-size: clamp(1rem, 2vw, 2rem);

  /* After: font-size tied to container — works everywhere */
  font-size: clamp(1rem, 3cqi, 2rem);
}

The power of container-relative units: a card title that scales with its container, whether that container is a full-width hero or a thumbnail in a related-posts widget. This single feature eliminates hundreds of lines of per-context sizing overrides in mature codebases.

Browser Support and Migration Strategy

As of 2026, Container Queries have 93.5% global browser support (Can I Use). All major browsers shipped stable support by mid-2023. The only significant gap is older Safari versions (pre-16.0, which dropped support for older iOS devices that can't upgrade past iOS 15). A progressive enhancement approach:

/* Base styles (no container query — works everywhere) */
.product-card { display: block; }
.product-card img { width: 100%; }

/* Enhanced layout when container queries are supported */
@supports (container-type: inline-size) {
  .card-wrapper { container-type: inline-size; }
  
  @container (min-width: 350px) {
    .product-card { display: grid; grid-template-columns: 120px 1fr; }
    .product-card img { width: 120px; }
  }
}

Browsers without container query support get a simple stacked layout — functional, if not optimal. Browsers with support get the enhanced grid layout. This is the correct approach for progressive enhancement: the base experience works for everyone; the enhanced experience works for modern browsers.

When NOT to Use Container Queries

  • Page-level layout (header, footer, main navigation): These ARE tied to the viewport, not a container. Media queries are still correct here.
  • Print stylesheets: Container queries don't apply to print. Use @media print.
  • Dark mode / prefers-reduced-motion / color scheme: These are user preferences, not layout constraints. Use @media (prefers-color-scheme: dark).
  • Extremely simple components: A button that's always 44px tall doesn't need container queries. Don't over-engineer.

The rule of thumb: if a component appears in multiple layout contexts with different widths, it benefits from container queries. If it only appears in one place with a predictable width, media queries are fine. The goal isn't to replace all media queries — it's to use the right tool for the right layer.

Found this helpful? Explore 100+ free online tools — no signup needed.