Container queries
A media query asks how wide the browser window is, so a card gets the same answer whether it sits in a narrow sidebar or a wide main column. A container query asks the card's own container instead. Follow one card used in a 250px sidebar and a 700px main column of a 1000px page: mark each slot with container-type: inline-size, let each card ask @container (min-width: 400px), and watch only the card with room go side by side. Then widen the sidebar to 450px without touching the window, and see its card switch too.
5 quick questions
Pick an answer to see why. Your score saves with your progress.
01A page is 1000px wide. A card sits in a 250px sidebar. What does @media (min-width: 600px) answer for that card?
A media query's width is the viewport's width. The window is 1000px, which is at least 600px, so every card on the page gets yes, wherever it sits.
02Which declaration makes .slot a query container that queries can ask about its width?
container-type: inline-size turns the element into a query container for size queries on its inline axis, which is its width in horizontal text.
03The sidebar .slot is 250px wide and is a container. Its card is styled by @container (min-width: 400px) { .card { display: flex; } }. Is the sidebar card flex?
The card asks its nearest ancestor container, the sidebar slot. 250px is less than 400px, so the rule inside does not apply and the card stays stacked.
04The grid changes the sidebar from 250px to 450px. The window stays 1000px. What happens to the sidebar card?
Container queries follow the container, not the window. 450px is at least 400px, so the query now says yes and display: flex applies.
05Why can't an @container rule change the width of the container it asks about?
An element is never its own query container; the rules style its descendants. container-type also applies inline-size containment, so a change inside cannot feed back into the container's width and flip the answer.
Glossary
- Viewport
- The visible area of the browser window. A media query's width is the viewport's width.
- Media query
- @media (...) { ... }: rules that apply when a test about the viewport or device is true.
- Query container
- An element whose size container queries can ask about. You make one with container-type.
- container-type
- The property that makes an element a query container. inline-size lets queries ask its width; size lets them ask its width and height.
- Container query
- @container (...) { ... }: rules that apply when a test about the element's nearest query container is true.
- Inline size
- An element's size along the direction text runs. In horizontal text, such as English or Arabic, it is the width.
- Size containment
- A rule that the element's size does not depend on its contents. container-type turns it on, so a query cannot loop.
Notes and sources
- A real browser does all of this at once, every time it lays out the page: it finds each container, sizes it, answers the queries and applies the matching rules. The figure does it one step at a time so you can see each part.
- The page drawing is to scale across (1000px of window) but approximate in height. The cards in the figure show only the lines that matter; the full style.css also sets body { margin: 0; }, the image size (120px tall, flex: 0 0 160px beside the text) and the text padding.
- A size query reads the query container's content box: its width without padding or border. The slots here have no padding, so that is the full column width.
- If an element has no ancestor container at all, its container query is "unknown" and the rules inside do not apply. That is why the card sits in a .slot: an element cannot be its own query container.
- Container size queries work in Chrome and Edge 105, Safari 16 and Firefox 110 or later (MDN browser compatibility data).
- Save the full page as index.html and the full stylesheet as style.css, open it in a window about 1000px wide, then change 250px to 450px in the grid and reload: the sidebar card switches to side by side.
Quiz Unlocks after the last step.