Introduction
Container queries let you style elements based on the size of their parent container rather than the viewport. This has been the most requested CSS feature for over a decade.
With media queries, a component uses the same breakpoints whether it's in a narrow sidebar or a wide content area. Container queries fix this — components adapt to their actual available space.
This fundamentally changes responsive design. Instead of page-level breakpoints, you get truly portable, self-contained UI components.
Key Concepts
Containment Context
.card-grid {
container-type: inline-size;
container-name: card-grid;
}
/* Shorthand */
.sidebar {
container: sidebar / inline-size;
}
Writing Container Queries
@container (min-width: 400px) {
.card {
display: grid;
grid-template-columns: 200px 1fr;
}
}
@container sidebar (max-width: 300px) {
.nav-item span { display: none; }
}
Container Query Units
.card-title {
font-size: clamp(1rem, 3cqi, 1.5rem);
}
Practical Examples
1. Responsive Card
.card-wrapper { container-type: inline-size; }
.card { display: flex; flex-direction: column; }
@container (min-width: 350px) {
.card { flex-direction: row; }
.card__image { width: 40%; flex-shrink: 0; }
}
2. Adaptive Navigation
.nav-container { container: nav / inline-size; }
.nav-links { display: flex; flex-direction: column; gap: 0.25rem; }
@container nav (min-width: 600px) {
.nav-links { flex-direction: row; gap: 1rem; }
}
3. Dashboard Widget
.widget-slot { container-type: inline-size; }
.chart-widget .legend { display: none; }
@container (min-width: 500px) {
.chart-widget .legend { display: flex; gap: 1rem; }
}
Best Practices
- Use container-type: inline-size unless you specifically need block-size queries.
- Name your containers when the page has multiple containment contexts.
- Combine with CSS Grid or Flexbox for maximum layout flexibility.
- Use container query units (cqi) for fluid typography within components.
- Keep container queries alongside the component styles they modify.
Common Pitfalls
- Forgetting container-type on the parent — @container query silently does nothing.
- Using container-type: size when inline-size suffices — breaks layouts.
- Trying to query the element's own size — only checks parent container.
- Containment prevents the element from sizing to its content in the contained axis.
Browser Support
Chrome 105+, Safari 16+, Firefox 110+, Edge 105+. ~92% global coverage. Non-queried defaults serve as natural fallback.
Related Guides
- CSS Grid Best Practices — combine grid with container queries
- CSS clamp() and Fluid Design — fluid sizing with container units
- CSS Custom Properties — use variables inside container-queried styles