Skip to content
Laviyx Learn

Try

CSS course menu

CSS Container Queries: Components That Respond to Their Container

Learn CSS container queries: container-type and container-name, @container rules, why they beat media queries for reusable components, container query units such as cqi, and practical card layouts.

Intermediate5 min readUpdated
On this page

Media queries ask "how wide is the screen?". But a card component might sit in a wide main column on one page and a narrow sidebar on another, on the very same screen. Container queries ask "how wide is my container?", so a component can adapt to the space it actually has.

Setting up a container#

Two steps:

  1. Mark an element as a container with container-type.
  2. Write @container rules for elements inside it.
CSS
.slot { container-type: inline-size; margin-bottom: 14px; border: 1px dashed #aaa; padding: 6px; }
.wide { width: 100%; }
.narrow { width: 220px; }

.card { display: grid; gap: 10px; padding: 10px; background: #eef3ff; border-radius: 8px; font-family: system-ui, sans-serif; }
.card .thumb { height: 80px; background: url("/lesson-assets/landscape-600.svg") center / cover; border-radius: 6px; }
.card h3 { margin: 0; }

@container (min-width: 380px) {
  .card { grid-template-columns: 140px 1fr; align-items: center; }
  .card .thumb { height: 100px; }
}
HTML
<div class="slot wide">
  <article class="card"><div class="thumb"></div><div><h3>Same card</h3><p>In a wide container: side by side.</p></div></article>
</div>
<div class="slot narrow">
  <article class="card"><div class="thumb"></div><div><h3>Same card</h3><p>In a narrow container: stacked.</p></div></article>
</div>
Result

Both cards use identical HTML and CSS. The one in the wide slot lays out side by side; the one in the 220px slot stacks, because each responds to the width of its own container.

  • container-type: inline-size lets descendants query the container's inline size (its width in horizontal writing). It is the value you will use almost every time.
  • A container cannot query itself: the @container rules style its descendants.

Naming containers#

When containers are nested, a query uses the nearest ancestor container. Name containers to target a specific one:

CSS
.sidebar { container: sidebar / inline-size; }   /* shorthand: name / type */

@container sidebar (max-width: 300px) {
  .widget-title { font-size: 1rem; }
}

Container query units#

Inside a container, these units are relative to the container's size, like vw is to the viewport:

Unit1% of the container's
cqiInline size (width)
cqbBlock size (height)
cqmin, cqmaxSmaller / larger dimension
CSS
.box { container-type: inline-size; border: 1px dashed #aaa; padding: 8px; margin-bottom: 8px; }
.box h2 { font-size: clamp(1rem, 8cqi, 2.5rem); margin: 0; }
HTML
<div class="box" style="width: 100%"><h2>Scales with its box</h2></div>
<div class="box" style="width: 240px"><h2>Scales with its box</h2></div>
Result

The heading size follows the width of its box, within the limits set by clamp().

Media queries or container queries?#

Use media queries forUse container queries for
Page-level layout: how many columns, where the sidebar goesReusable components: cards, widgets, product tiles
User and device preferences (dark mode, reduced motion, print)Anything placed in containers of different sizes

They work together: media queries decide the page layout, and container queries let each component fit whatever space that layout gives it.

Container size queries are supported in current versions of all major browsers.

Practice#

Practice exercise

Make a .profile component that shows the avatar above the name when its container is narrower than 300px, and beside the name (avatar on the left) when the container is at least 300px wide.

Show solution
CSS
.wrap { container-type: inline-size; border: 1px dashed #aaa; padding: 8px; margin-bottom: 10px; }
.profile { display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center; }
.avatar { width: 56px; height: 56px; border-radius: 50%; background: #9b5de5; flex: none; }

@container (min-width: 300px) {
  .profile { flex-direction: row; text-align: left; }
}
HTML
<div class="wrap" style="width: 200px">
  <div class="profile"><div class="avatar"></div><div><strong>Asha Rao</strong><br>Front-end developer</div></div>
</div>
<div class="wrap" style="width: 100%">
  <div class="profile"><div class="avatar"></div><div><strong>Asha Rao</strong><br>Front-end developer</div></div>
</div>
Result

Key takeaway#

Finished this lesson?