Viewport breakpoints are still useful, but they answer the wrong question for many components. A card, sidebar, or pricing module often needs to react to the space it has, not the size of the browser. Container queries let the parent define that space.
Start with containment
Mark the parent as a query container. Then write rules against the parent width instead of the viewport width.
.card-shell { container-type: inline-size; }
@container (min-width: 36rem) {
.card { grid-template-columns: 14rem 1fr; }
}This keeps the component portable. The same card can be narrow in a sidebar and wide in a content grid without adding modifier classes.
Use them for component contracts
A clean pattern is to define a small set of layout states. Avoid recreating your whole breakpoint system inside every component. Name the states in comments, document the expected ranges, and keep tokens shared.
Container queries are not a replacement for responsive design. They are the missing layer between global page layout and component behavior. Use viewport breakpoints for the page shell; use container queries for reusable modules.