CSS Container Queries: The Future of Responsive Design (2026)

Developer May 30, 2026 · OTPZap Team

For years developers wishlisted "responsive based on parent container, not viewport". In 2026, finally: container queries stable across all major browsers. But many developers still default to media query for everything, when container query is better suited for many situations.

This article covers container queries from basic to advanced patterns, plus when to use which between container query vs media query.

The Problem Container Queries Solve

For a long time, responsive design used media queries based on viewport size. Problem: reusable components used in multiple locations have different sizes despite same viewport.

Example: card component used in:

Media query doesn't help because viewport same for all three cases. Solution before container queries: use props or JavaScript to handle, not clean.

Container query: card adapts based on parent's size, not viewport. Different layouts for each context, from pure CSS.

Basic Syntax

Setup container:

.parent {
  container-type: inline-size;
  /* or "size" for both width + height */
  container-name: card-container; /* optional, for multiple containers */
}

Style based on container size:

@container (min-width: 400px) {
  .card {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 1rem;
  }
}

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

/* With named container */
@container card-container (min-width: 400px) {
  .card { padding: 2rem; }
}

Same card, in different parents, renders different layouts. Without JavaScript.

Practical Patterns

1. Adaptive Card Component

<div class="card-wrap">
  <article class="card">
    <img src="..." alt="...">
    <div class="content">
      <h3>Title</h3>
      <p>Description...</p>
    </div>
  </article>
</div>
.card-wrap {
  container-type: inline-size;
}

.card {
  display: grid;
}

/* Compact: stacked vertically */
.card .content { padding: 1rem; }

/* Wide: horizontal layout */
@container (min-width: 400px) {
  .card {
    grid-template-columns: 200px 1fr;
  }
}

@container (min-width: 700px) {
  .card {
    grid-template-columns: 300px 1fr;
  }
  .card .content { padding: 2rem; font-size: 1.1rem; }
}

2. Sidebar Widget

Adaptive widget: if sidebar persistent, vertical layout. If sidebar collapses to top bar, horizontal layout.

aside {
  container-type: inline-size;
}

.widget {
  display: flex;
  flex-direction: column;
}

@container (min-width: 600px) {
  .widget {
    flex-direction: row;
    justify-content: space-between;
  }
}

3. Form Field Layout

Form auto-adjusting label position based on available width:

.form {
  container-type: inline-size;
}

.field {
  display: grid;
  gap: 0.5rem;
}

@container (min-width: 500px) {
  .field {
    grid-template-columns: 200px 1fr;
    align-items: center;
  }
}

Form in narrow modal: label on top. Form on wide page: label on side.

4. Navigation Menu

nav {
  container-type: inline-size;
}

.menu {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

@container (min-width: 600px) {
  .menu {
    flex-direction: row;
    gap: 2rem;
  }
}

@container (max-width: 599px) {
  .menu-toggle {
    display: block; /* Show hamburger */
  }
  .menu {
    display: none;
  }
  .menu.open {
    display: flex;
  }
}

Container Query Units

Besides container queries, container queries also bring new units:

Use case: text scaling based on container, not viewport:

.parent {
  container-type: inline-size;
}

.title {
  font-size: clamp(1.5rem, 5cqw, 3rem);
  /* Scale based on container width, with min/max */
}

Title is 5% of container width, with minimum 1.5rem and maximum 3rem.

Container Query vs Media Query: When to Use Which

Use Media Query For:

Use Container Query For:

Performance Considerations

1. Browser Cost

Container queries trigger layout recalculation when container size changes. For most cases, minimal cost. But excessive container queries in deeply nested levels can impact performance.

Best practice: limit container hierarchy to 2-3 levels. Each component needing container is usually only 1 level.

2. Layout Containment

container-type: inline-size implicitly applies contain: layout style inline-size. Element becomes containing block. There are side effects:

Most cases this is desirable, but if your component relies on positioning to other ancestors, test carefully.

Browser Support 2026

Coverage 95%+ in 2026. For older browsers, fallback to media queries or JavaScript.

Common Pitfalls

1. Forgetting to Set container-type

Most common mistake. You write @container rule but forget to set parent as container. Rule doesn't apply.

/* Wrong - parent isn't container */
@container (min-width: 400px) {
  .card { ... }
}

/* Right */
.parent {
  container-type: inline-size; /* REQUIRED */
}
@container (min-width: 400px) {
  .card { ... }
}

2. Applying to Self Element

Container queries can't style elements that are themselves containers. The element becomes container, you style its descendants.

/* Wrong - .self is container, applied to itself */
.self {
  container-type: inline-size;
}
@container (min-width: 400px) {
  .self { padding: 2rem; } /* DOESN'T WORK */
}

/* Right - container styling outside @container, descendants inside */
.self {
  container-type: inline-size;
  padding: 1rem;
}
@container (min-width: 400px) {
  .self > .child { padding: 2rem; } /* WORKS */
}

3. Width 0 Issue

Elements with display: contents or no meaningful width, container doesn't work as expected. Container needs resolvable width.

4. Naming Collision

Multiple ancestors becoming containers, query can match ancestor you don't expect. Use container-name for specificity.

Closing

Container queries finally solve a long-standing problem in responsive design: components adapting to context, not viewport. Browser support now stable, syntax mature, performance acceptable.

In 2026, if you build component-based design systems, container queries should be default tool. Use media queries for page-level layouts, container queries for component-level adaptation.

What you don't need: rewrite all existing stylesheets to use container queries. Apply gradually for new components or components where current pattern is awkward with media queries.

Plus: explore container query units (cqw, cqh, etc.). They unlock fluid typography and spacing patterns previously needing JavaScript ResizeObserver.