CSS Container Queries: Component-Level Responsive Design
Tech Setup2 min read
TS
Published July 31, 2026 · Editorial policy

The Problem with Media Queries
Media queries respond to the viewport width. But components live inside containers that may be narrow (sidebar) or wide (main content). A card component shouldn't care about the screen size — it should care about its own container.
Container Query Basics
1. Define a Container
.card-wrapper {
container-type: inline-size;
container-name: card;
}
inline-size: Track the width (not height)container-name: Optional, useful when nesting containers
2. Query the Container
@container card (min-width: 400px) {
.card {
display: grid;
grid-template-columns: 200px 1fr;
}
}
@container card (max-width: 399px) {
.card {
display: flex;
flex-direction: column;
}
}
Practical Example: Card Component
HTML
<div class="card-wrapper">
<article class="card">
<img src="hero.jpg" alt="Hero" class="card-image" />
<div class="card-body">
<h3 class="card-title">Article Title</h3>
<p class="card-excerpt">Short description of the article...</p>
<div class="card-meta">
<span class="card-date">Jan 15, 2026</span>
<span class="card-tag">Tutorial</span>
</div>
</div>
</article>
</div>
CSS
/* Container */
.card-wrapper {
container-type: inline-size;
}
/* Base style (mobile-first) */
.card {
border: 1px solid #333;
border-radius: 8px;
overflow: hidden;
}
.card-image {
width: 100%;
height: 200px;
object-fit: cover;
}
.card-body {
padding: 1rem;
}
.card-title {
font-size: 1.25rem;
margin: 0 0 0.5rem;
}
/* Wide container: side-by-side layout */
@container (min-width: 500px) {
.card {
display: grid;
grid-template-columns: 250px 1fr;
}
.card-image {
height: 100%;
}
.card-title {
font-size: 1.5rem;
}
}
/* Extra wide: add more metadata */
@container (min-width: 800px) {
.card-meta {
display: flex;
gap: 1rem;
margin-top: 1rem;
padding-top: 1rem;
border-top: 1px solid #333;
}
.card-title {
font-size: 1.75rem;
}
}
Container Query Units
| Unit | Meaning |
|---|---|
cqw | 1% of container width |
cqh | 1% of container height |
cqi | 1% of container inline size |
cqb | 1% of container block size |
cqmin | Smaller of cqi and cqb |
cqmax | Larger of cqi and cqb |
Example: Fluid Typography
.card-wrapper {
container-type: inline-size;
}
.card-title {
font-size: clamp(1rem, 3cqi, 2rem);
}
The font scales with the container, not the viewport.
Nesting Containers
You can nest containers. Each query only affects its direct parent:
.sidebar {
container-type: inline-size;
container-name: sidebar;
}
.main-content {
container-type: inline-size;
container-name: main;
}
/* Card in sidebar */
@container sidebar (max-width: 300px) {
.card { /* compact layout */ }
}
/* Card in main content */
@container main (min-width: 600px) {
.card { /* expanded layout */ }
}
Named vs Anonymous Containers
/* Anonymous — catches all @container rules */
.parent { container-type: inline-size; }
/* Named — only responds to matching queries */
.parent { container-type: inline-size; container-name: parent; }
@container parent (min-width: 500px) { ... }
Use named containers when you have multiple container types on the page.
Browser Support (2026)
| Browser | Support |
|---|---|
| Chrome 105+ | ✅ |
| Firefox 110+ | ✅ |
| Safari 16+ | ✅ |
| Edge 105+ | ✅ |
Safe to use in production without fallbacks for modern browsers.
Container Queries vs Media Queries
| Feature | Media Query | Container Query |
|---|---|---|
| Responds to | Viewport | Parent container |
| Use case | Page layout | Component layout |
| Responsive to | Screen size | Available space |
| Nesting | N/A | Per-container |
Common Patterns
Grid Auto-Fit with Containers
.grid-wrapper {
container-type: inline-size;
}
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1rem;
}
/* Stack on narrow containers */
@container (max-width: 600px) {
.grid {
grid-template-columns: 1fr;
}
}
Sidebar Collapse
.layout {
container-type: inline-size;
}
@container (max-width: 768px) {
.sidebar { display: none; }
.main { width: 100%; }
}
@container (min-width: 769px) {
.sidebar { width: 250px; }
.main { flex: 1; }
}
Performance Notes
- Container queries add minimal overhead
- The browser already tracks layout for paint
- Use
contain: layout inline-sizefor best performance (set automatically bycontainer-type) - Avoid querying very deeply nested containers


