Container queries

CSS · Advanced · 12 min

A card that adapts to its slot works in a sidebar, a grid or full width without page-level breakpoints.

Media queries ask about the viewport, but a component doesn't know where it will be placed: the same card may sit in a narrow sidebar or a wide main column. Container queries let it respond to the space it actually has.

Two steps:

  • Mark an ancestor as a container: container-type: inline-size (query its width). Optionally name it with container-name: sidebar, or use the shorthand container: sidebar / inline-size.
  • Query it: @container (width >= 30rem) { ... }. Rules inside apply to descendants of the nearest container that matches (or the named one: @container sidebar (width >= 30rem)).

A container can't style itself based on its own size; queries apply to its descendants. And inline-size containment means the container's width must not depend on its children, which is normal for blocks and grid cells but not for shrink-to-fit elements. Use size only if you also need height queries, because it requires an explicit height.

Container query units size things relative to the container: cqi is 1% of its inline size, so font-size: clamp(1rem, 4cqi, 2rem) gives type that scales with the card.

Style queries like @container style(--variant: compact) query custom property values on the container (supported in Chromium and Safari; check support before relying on them).

Use media queries for page-level layout and container queries for reusable components.

Example

/* <div class="slot"><article class="card"><img><div>...</div></article></div> */
.slot { container-type: inline-size; }

.card { display: grid; gap: 0.75rem; }        /* narrow: stacked */
.card h2 { font-size: clamp(1rem, 5cqi, 1.75rem); }  /* scales with the slot */

@container (width >= 30rem) {                  /* wide slot: side by side */
  .card { grid-template-columns: 160px 1fr; }
}

/* named container */
.sidebar { container: sidebar / inline-size; }
@container sidebar (width < 15rem) {
  .card img { display: none; }
}

Remember

  • container-type: inline-size makes an element queryable
  • @container rules apply to descendants, never the container itself
  • cqi units size relative to the container
  • Media queries for pages, container queries for components

Watch out for

  • Querying an element's own size; the query must target an ancestor container.

Check yourself

  1. Why can't an element with container-type: inline-size use @container to change its own width?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: developer.mozilla.org/en-US/docs/Web/CSS/Guides/Containment/Container_queries

Builds on

Unlocks

Nothing builds on this yet.