CSS Superpower: Unlocking the Magic of Container Queries
Components that respond to the space they sit in rather than the viewport, and the one declaration people forget to add.
I hit this on a dashboard where the same card appeared in a narrow sidebar, a two-column main area, and a full-width settings page. Media queries couldn't help. The card only knew the window was 1400px wide, so in a 240px sidebar it still rendered a 2rem title across two lines. I shipped a wrapper div and a resize observer instead.
Container queries let a component ask about the box it sits in rather than the window.
What are Container Queries?
A media query asks how big the viewport is. A container query asks how big this element's parent is.
You opt a parent in as a container, then query it:
.card {
container-type: inline-size;
}
@container (min-width: 400px) {
.card-title {
font-size: 2rem;
}
}The container-type: inline-size line is the part I forget. Without it the @container block silently does nothing.
What Changes
- Components respond to their own space, so one card can work in a sidebar and in a wide column without knowing which it's in.
- Design system components stop needing props like
isNarrow, passed down from a page that happens to know the layout. - You can drop the wrapper divs and JS resize listeners you may have added to fake this.
Widgets and sidebars can rearrange themselves when they run out of room.
Where I Use Them
- Reusable UI components: buttons, cards, or widgets that need to work in more than one layout.
- Dynamic grids: items that reflow when a column narrows, which happens constantly once users start dragging the window.
- Complex layouts: sidebars and tool panels where font size or orientation should follow the panel width.
Real-World Example
A product card that stacks when it's cramped and goes horizontal when it has room:
.product-card {
container-type: inline-size;
display: flex;
flex-direction: column;
}
@container (min-width: 600px) {
.product-card {
flex-direction: row;
}
.product-image {
width: 300px;
}
}In a tight sidebar it stacks. On a roomy page the image moves to the side. Same markup, same CSS.
Beyond Width
Width is the common case, but @container can query height and other container features too. Support is good enough now that I reach for container queries first when styling a component in isolation.
If one of your components keeps breaking in a narrow column, that's the one to convert first.