IAnswerable

Container Queries Change How You Write CSS

27 Oct 2026

Media queries answer “how wide is the viewport.” That’s the wrong question for most components. A card in a three-column grid and the same card full-width in a sidebar need different layouts at the same viewport width. Container queries answer “how wide is the space this component actually has,” which is almost always what you meant.

The setup

Container queries need a containment context. You opt an element in with container-type, then query against it from descendants:

.card-grid {
  container-type: inline-size;
  container-name: cards;
}

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

@container cards (min-width: 400px) {
  .card {
    grid-template-columns: 120px 1fr;
  }
}

container-type: inline-size tells the browser to track the container’s inline (usually horizontal) size and lets you query it. container-name is optional — skip it and @container matches the nearest ancestor container, which is fine until you nest two containers and need to target a specific one.

Why this replaces a pile of viewport breakpoints

Before container queries, a reusable card component had two bad options: hardcode one layout regardless of context, or sprinkle .sidebar .card { } overrides for every place you drop it. Neither scales. With a container query, the card decides its own layout based on the space it’s actually given, so it looks right in a 3-column grid, a 1-column sidebar, and a modal, without any consumer-side overrides.

The gotcha: you can’t query your own container

A container query can’t read the size of the element you put container-type on — only its descendants. This trips people constantly:

/* This does NOT work — .card queries itself */
.card {
  container-type: inline-size;
}
@container (min-width: 400px) {
  .card { grid-template-columns: 120px 1fr; }
}

Fix: put container-type on the parent, and query from the child.

.card-wrapper {
  container-type: inline-size;
}
@container (min-width: 400px) {
  .card { grid-template-columns: 120px 1fr; }
}

If your component is a single element with no wrapper, add one. It’s usually one extra div, which is a fair trade for layout that actually reflects context.

Container query units

You also get cqw, cqh, cqi, cqb — percentages of the container’s dimensions instead of the viewport’s. Useful for fluid type inside a card that needs to scale with the card, not the window:

.card-title {
  font-size: clamp(1rem, 4cqi, 1.5rem);
}

Browser support

Support has been solid across Chrome, Safari, and Firefox for a while now — this isn’t bleeding edge. If you still need to support something ancient, wrap the query in @supports (container-type: inline-size) and ship a sane single-column fallback outside it.

When to still use a media query

Page-level layout — is there a sidebar at all, is the nav a hamburger — is still a viewport question. Container queries are for components that get reused in more than one place. Use both: media queries for the page shell, container queries for everything that lives inside it.