CSS Container Queries

Difficulty: Advanced

Question

What are CSS container queries? How do they differ from media queries?

Answer

Container queries style elements based on their PARENT container's size, not the viewport.

Media queries: respond to viewport width (global) Container queries: respond to container width (component-level)

This enables truly reusable responsive components that adapt to wherever they're placed - sidebar, main content, or full-width.

Setup: 1. Define a container: container-type: inline-size on parent 2. Query it: @container (min-width: 400px) { }

Container query units: cqw, cqh, cqi, cqb (like vw/vh but for container).

Code examples

Basic Container Query

/* 1. Define a containment context */
.card-container {
  container-type: inline-size;
  /* inline-size: query width only */
  /* size: query width and height */
  /* normal: no containment (default) */
}

/* 2. Optionally name it */
.sidebar {
  container-type: inline-size;
  container-name: sidebar;
}
/* Shorthand */
.sidebar {
  container: sidebar / inline-size;
}

/* 3. Query the container */
.card {
  display: flex;
  flex-direction: column;
}

@container (min-width: 400px) {
  .card {
    flex-direction: row;
    /* Card goes horizontal when container is wide */
  }
}

/* Named container query */
@container sidebar (min-width: 300px) {
  .widget { font-size: 1.125rem; }
}

The card layout changes based on its container width, not the viewport. The same card component works in a narrow sidebar and a wide main area.

Container Query Units

/* Container query units */
.card-container {
  container-type: inline-size;
}

.card__title {
  /* cqw: 1% of container's inline size (width) */
  font-size: clamp(1rem, 4cqw, 2rem);
}

.card__image {
  /* Responsive to container, not viewport */
  height: 30cqw;
  object-fit: cover;
}

/* Available units:
  cqw - container query width (1%)
  cqh - container query height (1%)
  cqi - container query inline size
  cqb - container query block size
  cqmin - smaller of cqi/cqb
  cqmax - larger of cqi/cqb
*/

/* Fluid spacing based on container */
.card__body {
  padding: clamp(0.75rem, 3cqw, 2rem);
}

Container query units are like viewport units (vw, vh) but relative to the container. They enable fluid sizing that adapts to the component's context.

Real-World: Adaptive Component

/* A product card that adapts everywhere */
.product-grid {
  container-type: inline-size;
}

.product-card {
  display: grid;
  gap: 0.75rem;
  padding: 1rem;
}

/* Small container: stack vertically */
.product-card__image { aspect-ratio: 16/9; }
.product-card__price { font-size: 1.25rem; }

/* Medium container: side by side */
@container (min-width: 350px) {
  .product-card {
    grid-template-columns: 120px 1fr;
    align-items: start;
  }
  .product-card__image {
    aspect-ratio: 1;
  }
}

/* Large container: more details */
@container (min-width: 600px) {
  .product-card {
    grid-template-columns: 200px 1fr auto;
  }
  .product-card__actions {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
  }
}

/* Works in sidebar (narrow),
   main content (medium),
   or full-width (large) */

This product card adapts its layout based on how much space it has, regardless of viewport size. Drop it in any container and it just works.

Key points

Concepts covered

Container Queries, Containment, Responsive Components, container-type, cqw units