Container Queries
Container Queries allow components to respond to their container’s size rather than the viewport, enabling truly reusable responsive components.
The Old Way
Section titled “The Old Way”/* Media queries respond to viewport only */.card { display: flex; flex-direction: column;}
.card-image { width: 100%;}
@media (min-width: 600px) { .card { flex-direction: row; } .card-image { width: 200px; }}
/* Problem: Same card in a narrow sidebar still gets the "wide" layout because viewport is wide, not the container */// JavaScript workaroundconst observer = new ResizeObserver((entries) => { for (const entry of entries) { const width = entry.contentRect.width; entry.target.classList.toggle('wide', width > 400); }});observer.observe(document.querySelector('.card-container'));Problems:
- Media queries only respond to viewport size
- Same component behaves differently based on page layout
- JavaScript required for container-aware styling
- Components not truly portable between contexts
- Resize observers add complexity and performance overhead
The Modern Way
Section titled “The Modern Way”/* Define a containment context */.card-container { container-type: inline-size; container-name: card;}
/* Shorthand */.card-container { container: card / inline-size;}
/* Component responds to container size */.card { display: flex; flex-direction: column;}
.card-image { width: 100%;}
@container card (min-width: 400px) { .card { flex-direction: row; } .card-image { width: 200px; }}Benefits:
- Components respond to their container, not viewport
- Truly reusable components across different contexts
- No JavaScript required
- Works in sidebars, modals, grids—anywhere
- Declarative CSS solution
Advanced Patterns
Section titled “Advanced Patterns”Container Query Units
Section titled “Container Query Units”.card-container { container-type: inline-size;}
.card-title { /* cqi = 1% of container's inline size */ font-size: clamp(1rem, 5cqi, 2rem);}
.card-description { /* Container query units */ padding: 2cqi;}| Unit | Description |
|---|---|
cqw | 1% of container’s width |
cqh | 1% of container’s height |
cqi | 1% of container’s inline size |
cqb | 1% of container’s block size |
cqmin | Smaller of cqi or cqb |
cqmax | Larger of cqi or cqb |
Multiple Container Queries
Section titled “Multiple Container Queries”.card-container { container: card / inline-size;}
@container card (min-width: 300px) { .card { padding: 16px; }}
@container card (min-width: 500px) { .card { padding: 24px; gap: 16px; }}
@container card (min-width: 700px) { .card { padding: 32px; gap: 24px; }}Nested Containers
Section titled “Nested Containers”.sidebar { container: sidebar / inline-size;}
.widget { container: widget / inline-size;}
/* Widget responds to sidebar */@container sidebar (max-width: 300px) { .widget { font-size: 14px; }}
/* Widget content responds to widget */@container widget (min-width: 200px) { .widget-content { display: grid; grid-template-columns: 1fr 1fr; }}Style Container Queries
Section titled “Style Container Queries”.card-container { container-type: inline-size; --theme: light;}
.card-container.dark { --theme: dark;}
/* Query custom property values */@container style(--theme: dark) { .card { background: #1a1a1a; color: white; }}Browser Support
Section titled “Browser Support”Supported in all modern browsers. See caniuse.com/css-container-queries.
Style container queries have more limited support. See caniuse.com/css-container-queries-style.
Performance Considerations
Section titled “Performance Considerations”container-type: inline-sizecreates layout containment- Containment prevents certain layout calculations from propagating
- Generally good performance, but avoid deeply nested containers
- Container query units are calculated at layout time
When to Use
Section titled “When to Use”Use Container Queries when:
- Building reusable components that appear in different contexts
- Component layout should depend on available space, not viewport
- Creating widget systems for dashboards
- Building card components for grids of varying column counts
- Components may appear in sidebars, modals, or main content
Keep using Media Queries when:
- Responding to viewport-level changes
- Changing overall page layout
- Handling print stylesheets
- Adjusting for device capabilities (hover, pointer)