Viewport breakpoints are global guesses. They answer “how wide is the browser?” when many component bugs are really asking “how much room did this component get?”
Container queries are useful when a component can appear in multiple contexts: a card in a three-column grid, the same card in a sidebar, and the same card in a detail page. A viewport media query cannot know those contexts. A container query can.
Establish the query boundary
The parent that owns available space needs containment.
.card-region {
container-type: inline-size;
}
.product-card {
display: grid;
gap: 1rem;
}
@container (min-width: 32rem) {
.product-card {
grid-template-columns: 12rem 1fr;
align-items: start;
}
}
This reads as a component rule, not a page rule. When the card region is wide enough, the card gets a media object layout. When it is narrow, it stacks.
Query the context, not every element
Avoid wrapping every component in unnecessary query containers. Choose a stable layout boundary such as a sidebar region, grid cell, card rail, or content module. The goal is not to replace every media query. The goal is to keep component behavior near the component.
Watch intrinsic sizing
Container queries do not remove the need for good sizing rules. A child with a long URL, a wide table, or a fixed-width image can still overflow. Use constraints that allow content to shrink.
.product-card {
min-inline-size: 0;
}
.product-card img {
inline-size: 100%;
max-inline-size: 100%;
block-size: auto;
}
When media queries still win
Use viewport media queries for page-level decisions: navigation shell changes, global spacing shifts, print behavior, and anything tied to device or viewport conditions. Use container queries for component layout decisions. Mixing both is normal. The important part is keeping each rule responsible for the right question.
Production checklist
Before shipping a container-query component, place it in at least three real containers. Test a narrow sidebar, a medium content column, and a wide main region. If the same component survives those contexts without new wrapper classes, the query boundary is probably doing useful work.