Responsive components without media queries
Media queries respond to the viewport. Components live in containers: sidebars, modals, grids. @container lets them respond to their actual available space.
2 display: grid;
3 grid-template-columns: 1fr;
4}
5
6@media (min-width: 768px) {
7 .card {
8 grid-template-columns: auto 1fr;
9 }
10}
11/* Breaks when .card is in a sidebar */
2 container-type: inline-size;
3}
4
5.card { grid-template-columns: 1fr; }
6
7@container (width > 400px) {
8 .card {
9 grid-template-columns: auto 1fr;
10 }
11}
12/* Adapts to its container, not viewport */
Component-level responsive
Components adapt to their own container. Same card works in a sidebar, modal, or full-width grid.
Truly reusable
No more breakpoint math for every context. The component carries its responsive logic with it.
Precise control
Query the nearest container, not the whole viewport. Each section of the page can behave independently.
How it works
First, mark a parent as a container with container-type: inline-size. This tells the browser to track its width for query purposes.
Then use @container (width > 400px) instead of @media. The query now fires based on the container's width, not the viewport. Your card can be 300px wide in a sidebar and 800px wide in a main area, and it'll adapt correctly in both.
You can even name containers with container-name to target specific ancestors when nesting multiple containers.