Media queries have served us well for decades. However, they suffer from a major design limitation: styling is bound to the total viewport width. If you build a card component, it doesn't care if it lives in a narrow sidebar or a wide grid—you must write custom overrides for each context. Container Queries fix this permanently.
What are Container Queries?
Container queries allow you to observe the dimensions of a specific parent container element, rather than the browser window viewport. This means components can look wide and layout horizontally when placed in a large area, and collapse into a vertical stacked layout when placed in a narrow sidebar or card.
Step 1: Setting up the Container
First, we designate a parent container using CSS. We set the container-type property to inline-size, indicating we want to observe width changes:
.widget-container {
container-type: inline-size;
container-name: card-container;
width: 100%;
}Step 2: Writing Container Queries
Now, instead of using @media, we use @container to target the container size directly. The component layout transitions adaptively:
.profile-card {
display: flex;
flex-direction: column;
gap: 1rem;
padding: 1rem;
background: white;
}
/* When parent card-container width is 450px or wider */
@container card-container (min-width: 450px) {
.profile-card {
flex-direction: row;
align-items: center;
padding: 1.5rem;
}
.profile-card img {
width: 120px;
height: 120px;
}
}Why this matters
By decoupling your CSS styling from the browser viewport, you gain a brand new power: Contextual UI Independence. You can place the exact same card in your layout's main grid column, sidebar, or footer, and it will render perfectly without any custom modifier classes!
