Container Queries
Media queries ask “how wide is the screen?” Container queries ask “how wide is THIS component?” — so a card can adapt to wherever it is placed.
What you will learn
- Explain how container queries differ from media queries
- Set up a query container with container-type
- Style a component based on its own width
Why media queries are not enough
You already know media queries: they react to the viewport (the whole screen) — for example “below 600px, stack the cards”. But the same component often lives in different places: a product card might be full-width on one page and squeezed into a narrow sidebar on another. The screen size is identical in both, yet the card needs to look different.
Container queries solve this. Instead of asking “how wide is the screen?”, they ask “how wide is my container (my parent box)?” — so a component can adapt to the space it is actually given, no matter where you drop it.
Note: Plain-English definition: a container query styles an element based on the width (or height) of an ancestor you have marked as a “container”, rather than the width of the whole browser window.
The two steps
Setting up a container query is always the same two steps:
- On the parent box, declare it a container with
container-type: inline-size(this means “measure my width”). Optionally give it a name withcontainer-name. - Write a
@containerrule — just like@media, but it tests the container’s width instead of the screen’s — and put the styles that should change inside it.
A card that adapts to its container
Below, the same card markup is placed in a wide box and a narrow box. With container queries, the wide one lays its image and text side by side, while the narrow one stacks them — even though the screen size never changed. Read the code, then the breakdown:
<style>
/* Step 1: mark the wrapper as a query container */
.col { container-type: inline-size; border: 1px dashed #c7d2fe; padding: 8px; border-radius: 10px; }
.wide { width: 100%; margin-bottom: 14px; }
.narrow { width: 230px; }
.card { background: #eef2ff; border-radius: 10px; padding: 12px; }
.card img { width: 100%; border-radius: 8px; }
.card h4 { margin: 8px 0 4px; color: #4338ca; }
/* Step 2: when the CONTAINER is at least 380px wide, go side-by-side */
@container (min-width: 380px) {
.card { display: flex; gap: 12px; align-items: center; }
.card img { width: 120px; }
}
</style>
<div class="col wide">
<div class="card">
<img src="https://picsum.photos/200/120" alt="photo">
<div><h4>Wide container</h4><p>Image and text sit side by side.</p></div>
</div>
</div>
<div class="col narrow">
<div class="card">
<img src="https://picsum.photos/200/120" alt="photo">
<div><h4>Narrow container</h4><p>Same card — now stacked.</p></div>
</div>
</div>The two cards have identical markup, yet they look different because each sits in a container of a different width. Here is why:
container-type: inline-sizeon.col— this is the key line. It tells the browser “measure this box’s width and let children query it”. (“Inline size” means width in a normal left-to-right page.)@container (min-width: 380px) { ... }— reads just like a media query, but it checks the nearest container’s width, not the screen. The wide.colis over 380px, so its card switches todisplay: flex(image beside text). The narrow.colis only 230px, so the rule does not apply and its card stays stacked.- Resize the whole preview and notice: even on a wide screen, the narrow card stays stacked — because it is the container, not the screen, that decides.
Note: Output: The top card (in a full-width container) shows its image and text side by side; the bottom card (in a 230px container) shows the same image and text stacked vertically — purely because their containers are different widths.
Tip: There are container units too: cqw is 1% of the container’s width and cqi is 1% of its inline size. So font-size: 5cqi makes text scale with the component’s own width — perfect for truly self-contained, reusable components.
Watch out: A container query reads the nearest ancestor marked with container-type — never the element itself. If nothing changes, check that you put container-type on a parent, not on the element you are trying to style.
Q. What does a container query respond to?
✍️ Practice
- Mark a sidebar and a main column as containers, then put the same card in both and make it stack only in the narrow one.
- Use a
cqiunit on a heading so its size scales with its container’s width.
🏠 Homework
- Take your landing-page feature card and make it fully container-aware: side-by-side when it has room, stacked when it does not — without a single media query.