Mission log
Same component, three layouts
This card doesn’t know about the viewport. It only reacts to the width of the box it sits in, so it looks right in a sidebar, a modal, or a full-width section without a single extra class.
container-type / @container
Media queries respond to the viewport. Container queries respond to the box the component is actually sitting in, so the same card can look right in a narrow sidebar and a wide main column without a wrapper class for every context.
The CSS
.container {
container-type: inline-size;
container-name: demo-card;
}
.card {
display: flex;
flex-direction: column;
@container demo-card (min-width: 380px) {
flex-direction: row;
}
}
.title {
font-size: clamp(1rem, 5.2cqi, 1.3rem);
}Mark an ancestor as a query container with container-type: inline-size (and optionally name it with container-name). Anything inside can then use @container (min-width: 380px) instead of @media, and it recalculates against the container’s box, not the browser window.
Container query length units are useful too: cqi (a percentage of the container’s inline size) lets the heading above scale with the card itself, which a vw unit could never do for a component that isn’t full-width.
All evergreen browsers (Chrome/Edge 105+, Safari 16+, Firefox 110+)