For years, responsive web design relied exclusively on Media Queries (@media). While media queries are excellent for altering page layouts based on the screen size, they have a major flaw when building modular component libraries: they only know about the viewport, not where the component resides on the page.

CSS Container Queries (@container) solve this by enabling components to adapt their layouts based on the dimensions of their parent container.


1. The Core Limitation of Viewport Media Queries#

Imagine you build a Card component.

  • If the card is rendered in the main page area, it should show a wide, horizontal layout.
  • If the card is rendered inside a narrow sidebar, it should show a compact, vertical stack layout.

If you use media queries, you cannot easily do this. A media query checks the viewport width. If the viewport is 1200px, the card will render in its horizontal layout even when forced inside a narrow 300px sidebar container.

CSS
/* Media query only checks the viewport width */
@media (min-width: 768px) {
  .card {
    display: flex; /* Forces horizontal layout on large screens, even inside a sidebar! */
  }
}

2. Setting Up Container Queries#

To use container queries, you must follow a two-step process:

  1. Define the Container Parent: Mark the wrapper element as a container that the browser should watch.
  2. Query the Container: Write container queries on the child elements.

Step 1: Define the Container#

We use the container-type property to specify what kind of container to watch.

CSS
.card-wrapper {
  /* container-type can be 'size' (width and height) or 'inline-size' (width only) */
  container-type: inline-size;
  
  /* Optional: Name the container if you have multiple nested containers */
  container-name: card-container;
}

Step 2: Query the Container Size#

Now, we apply styles to the .card component depending on the width of the .card-wrapper.

CSS
/* Compact vertical layout by default */
.card {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* If the container parent is wider than 400px, display horizontally */
@container (min-width: 400px) {
  .card {
    flex-direction: row;
    align-items: center;
  }
}

3. Container Query Units#

Just as we have viewport units (vw, vh), CSS Container Queries introduce Container Query Units:

  • cqw: 1% of the container's width.
  • cqh: 1% of the container's height.
  • cqi: 1% of the container's inline-size (width in horizontal writing modes).
  • cqb: 1% of the container's block-size.
  • cqmin: The smaller value of cqi or cqb.
  • cqmax: The larger value of cqi or cqb.

These units allow you to style sub-elements (like heading font sizes) proportionally to their parent's width.

CSS
.card-title {
  /* Font size automatically scales with container width, not screen width! */
  font-size: clamp(1rem, 6cqi, 1.5rem);
}

Key Takeaways#

  • Media queries evaluate the browser window size. Container queries evaluate parent container elements.
  • To create a container, apply container-type: inline-size to the parent element.
  • Child elements are styled using @container (min-width: ...px) { ... }.
  • Container query units (like cqw and cqi) make element sizes and typography responsive to the immediate parent dimensions.