Quick take: - Container queries let a component respond to its parent's size, not the viewport. Add
container-type: inline-sizeto any wrapper element, then use@container (min-width: ...)to write context-aware styles inside it. Browser support is 93%+ as of 2026. Use them alongside media queries - not instead of them.
Media queries check the viewport. CSS container queries check the container instead. This distinction is fundamental to building truly responsive, reusable components. Container queries (size type) are supported in all major browsers since Chrome 105, Safari 16, and Firefox 110 - overall support sits at around 93% as of early 2026. In our own projects, switching to container queries eliminated the need to maintain viewport-specific overrides for shared components.
What's Wrong with Media Queries for Component Design?
Imagine a Card component that looks great in a 3-column grid but breaks when placed in a sidebar. With media queries, you'd need to know the context at the component level - which defeats the purpose of encapsulation.
Container queries solve this: the component adapts to wherever it's placed.
What Is the Basic Container Query Syntax?
/* 1. Define a containment context on the parent */
.card-wrapper {
container-type: inline-size;
/* Optionally name it */
container-name: card;
}
/* 2. Query the container inside the component */
@container (min-width: 400px) {
.card {
display: grid;
grid-template-columns: auto 1fr;
}
}
@container (min-width: 600px) {
.card {
gap: 2rem;
}
}
Named containers
Name containers when you have nested containment contexts:
.sidebar { container-type: inline-size; container-name: sidebar; }
.main { container-type: inline-size; container-name: main; }
@container sidebar (min-width: 300px) {
.widget { /* only applies when inside .sidebar */ }
}
@container main (min-width: 600px) {
.widget { /* only applies when inside .main */ }
}
How Do You Build a Truly Adaptive Card Component?
<div class="card-wrapper">
<article class="card">
<img class="card__image" src="..." alt="...">
<div class="card__body">
<h2 class="card__title">Article title</h2>
<p class="card__desc">Description text...</p>
<a class="card__cta">Read more</a>
</div>
</article>
</div>
.card-wrapper {
container-type: inline-size;
}
/* Mobile-first: stacked layout */
.card {
display: flex;
flex-direction: column;
gap: 1rem;
padding: 1.25rem;
}
.card__image {
width: 100%;
aspect-ratio: 16/9;
object-fit: cover;
border-radius: 8px;
}
/* Wider container: side-by-side layout */
@container (min-width: 480px) {
.card {
flex-direction: row;
align-items: flex-start;
}
.card__image {
width: 180px;
aspect-ratio: 1;
flex-shrink: 0;
}
}
/* Very wide container: larger typography */
@container (min-width: 700px) {
.card__title { font-size: 1.5rem; }
.card__desc { font-size: 1rem; }
}
Now this card looks correct in a 1-column feed, a 3-column grid, and a narrow sidebar - with zero changes to the component markup.
What Are the New Container Query Units?
CSS also introduces new units based on container size:
| Unit | Equivalent to |
|---|---|
cqi | 1% of inline size |
cqb | 1% of block size |
cqw | 1% of container width |
cqh | 1% of container height |
cqmin | Smaller of cqw/cqh |
cqmax | Larger of cqw/cqh |
.card__title {
font-size: clamp(1rem, 4cqi, 2rem);
/* scales with container width, not viewport */
}
Scaling type with cqi is one part of the picture; the other is choosing the right typeface and scale ratios so the typography reads well at every size the container allows. The web typography and font pairing guide on Art of Styleframe covers type scale construction, variable font setup, and the clamp()-based fluid typography approach that pairs directly with container query units.
What Are CSS Style Queries?
Style queries (still experimental in some browsers) let you query CSS custom property values:
@container style(--layout: horizontal) {
.card {
flex-direction: row;
}
}
This enables "variant-driven" component styling from outside via CSS variables.
Browser Support and Fallbacks
Container queries (size type) landed in all major browsers between mid-2022 and early 2023. Chrome 105 (August 2022) shipped first, Safari 16 followed in September 2022, and Firefox 110 arrived in February 2023. As of early 2026, global support sits at roughly 93% according to caniuse.com. That's high enough that you don't need to guard every query behind a feature check for new projects.
That said, 7% is still real users. Here's how to handle them without breaking layouts.
Progressive enhancement with @supports:
/* Default layout - works everywhere */
.card {
display: flex;
flex-direction: column;
}
/* Only apply container query if supported */
@supports (container-type: inline-size) {
.card-wrapper {
container-type: inline-size;
}
@container (min-width: 480px) {
.card {
flex-direction: row;
}
}
}
The fallback stacks vertically - not ideal, but functional. Older browsers simply ignore the @supports block.
PostCSS plugin option: If you need broader compatibility, @csstools/postcss-container-queries compiles container queries into a JavaScript-driven polyfill at build time. I'd only reach for this on sites where IE 11 or older Android WebViews are genuine concerns - for most React or Astro apps, native browser support is sufficient.
Style queries: These are still experimental. Chrome 111+ supports them, but Firefox hasn't shipped them as of early 2026. Don't use style queries in production without an @supports guard, and treat them as a progressive enhancement only.
One practical tip: don't add container-type to every element by default. Each containment context has a small layout cost. Apply it only to wrapper elements where you actually write @container queries. And if you're still deciding between Grid and Flexbox inside those containers, check out the CSS Grid vs Flexbox comparison for a clear decision framework.
When to Use Container Queries vs Media Queries
- Container queries: Component-level adaptation (cards, widgets, sidebars)
- Media queries: Page-level layout (number of columns, navigation pattern, font scale)
- Both: A responsive page layout (media query) containing adaptive components (container queries)
Start adding container-type: inline-size to your component wrappers today. It's a low-risk addition and immediately unlocks better responsive behaviour across your component library. The pattern is straightforward: one property on the wrapper, one @container block per breakpoint you care about.
Further Reading
- MDN: CSS Container Queries - complete specification, browser support, and named container reference
- Can I use: CSS Container Queries - live browser support table
- MDN: Container query length units - full reference for
cqi,cqb,cqw,cqh,cqmin,cqmax
Related
- CSS Grid vs Flexbox: How to Choose the Right Layout - container queries work best when you've already picked the right layout tool for your component structure
- React Hooks pitfalls - if you're building React components with container-query-driven layouts, solid hook patterns keep your resize logic clean
- shadcn/ui - copy-paste component library built on Tailwind CSS; container queries make its Card and layout components truly context-aware
- Radix UI - unstyled accessible primitives you can style freely with container-query-driven CSS
- Headless UI - Tailwind-first components from the Tailwind Labs team that pair naturally with container query layouts