A Practical Guide to CSS Container Queries
This post started as a note to my future self. Every few months I relearn the same lessons about container queries, so this time I'm writing them down.
Most of the complexity was accidental. Over the years we'd layered three different approaches to container queries on top of each other, and each one made sense at the time.
How we got here
When we finally measured, the numbers were worse than anyone guessed. Around 24% of the time spent on a typical change went into working around container queries rather than building anything.
The setup was ordinary: Svelte at the edges, Storybook doing most of the heavy lifting, and a handful of scripts nobody wanted to own. It worked well until usage roughly doubled over a single quarter.
Trying something different
Rather than a big-bang rewrite, we migrated one module at a time over about 11 weeks, keeping both paths alive behind a flag.
The core of it looks like this:
.card-list {
container-type: inline-size;
}
@container (min-width: 36rem) {
.card {
display: grid;
grid-template-columns: 12rem 1fr;
gap: 1.5rem;
}
}
This alone let us delete a surprising amount of code elsewhere in the project.
A few things that helped along the way:
- Pair on the first few changes so the knowledge doesn't live in one head.
- Measure before and after, even if it's just a rough number in a spreadsheet.
- Keep the old path around until the new one has survived a real incident.
Caveats
The biggest cost was social, not technical. Changing how people think about container queries takes much longer than changing the code.
There are cases where this falls apart. If your team is very small or your traffic is very spiky, the extra moving parts may not pay for themselves.
What's next
That's it for now. Next time I'll dig into Core Web Vitals, which turned out to be closely related.