CSS Container Queries (@container)
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.
/* 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:
- Define the Container Parent: Mark the wrapper element as a container that the browser should watch.
- 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.
.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.
/* 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 ofcqiorcqb.cqmax: The larger value ofcqiorcqb.
These units allow you to style sub-elements (like heading font sizes) proportionally to their parent's width.
.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-sizeto the parent element. - Child elements are styled using
@container (min-width: ...px) { ... }. - Container query units (like
cqwandcqi) make element sizes and typography responsive to the immediate parent dimensions.