Container Queries
Introduction
Media queries adapt layouts based on viewport size, but components are often rendered inside containers of very different widths. A card in a narrow sidebar should not look the same as the same card in a wide main content area. This chapter introduces container queries, which let components respond to their own container size instead of only the global viewport.
Prerequisites
- Responsive design fundamentals
- Media queries and breakpoints
- Basic Flexbox/Grid component layout knowledge
Why Container Queries
Media queries answer:
- "How wide is the viewport?"
Container queries answer:
- "How wide is this component's container?"
This is crucial for reusable components in:
- sidebars
- cards inside different page regions
- dashboard widgets
- embedded modules in CMS layouts
The same component can adapt locally without page-level breakpoint coupling.
Core Setup: Declaring a Query Container
Before using @container, mark a parent as a container.
.card-shell {
container-type: inline-size;
}Code explanation:
container-type: inline-sizeenables size queries based on container width in writing direction- descendants can now use
@containerrules referencing this container - this keeps component responsiveness local and reusable
Basic Container Query Syntax
.product-card {
display: grid;
gap: 0.75rem;
}
@container (min-width: 480px) {
.product-card {
grid-template-columns: 120px 1fr;
align-items: start;
}
}Code explanation:
- base style is mobile/compact by default
- when container width reaches
480px, card switches to two-column layout - behavior depends on parent container width, not viewport width
Naming Containers
You can give containers explicit names for clarity in larger layouts.
.card-shell {
container-type: inline-size;
container-name: card;
}
@container card (min-width: 480px) {
.product-card {
grid-template-columns: 120px 1fr;
}
}Code explanation:
container-name: cardlabels this query context@container card (...)targets that named container- helps avoid ambiguity when nested containers exist
Container Queries vs Media Queries
Use media queries when:
- whole page structure changes by viewport
- global nav/header/footer behavior changes
Use container queries when:
- component layout depends on available local space
- same component appears in multiple host contexts
In real projects, they usually work together.
Practical Pattern: Adaptive Card Component
Result:
- narrow shell -> stacked avatar + text
- wider shell -> horizontal avatar + text layout
Same component, smarter local adaptation.
Practical Pattern: Widget Density Tuning
This pattern is excellent for dashboards where widget widths vary by panel placement.
Nested Layouts and Scoped Responsiveness
Container queries reduce global breakpoint complexity in nested UIs:
- page layout can stay viewport-driven
- each component can self-adjust internally
This avoids writing many page-specific override selectors like:
.sidebar .card ....main .card ...
Component CSS becomes more portable and maintainable.
Container Query Units (Quick Note)
You may also see container-relative units:
cqw,cqh,cqi,cqb,cqmin,cqmax
Example:
.title {
font-size: clamp(1rem, 3cqi, 1.5rem);
}These are useful but not required for getting started. Begin with @container conditions first.
Progressive Enhancement and Fallback
Not all environments may fully support every modern feature combination.
Safe strategy:
- write a solid base layout first
- enhance with container queries
- optionally guard advanced behavior with feature checks
Example:
@supports (container-type: inline-size) {
.card-shell {
container-type: inline-size;
}
}Even without container query support, base layout should remain usable.
Tip
Base First, Enhance Second
Treat container queries as enhancement, not a requirement for core readability and interaction.
Common Mistakes
| Mistake | Why it hurts | Better approach |
|---|---|---|
Forgetting to set container-type | Queries never trigger | Define container context explicitly |
| Using only viewport queries for reusable components | Excessive context-specific overrides | Move local adaptation to container queries |
| Over-querying tiny style tweaks | Unnecessary complexity | Use container queries for meaningful structural shifts |
| No base style before query blocks | Poor fallback behavior | Build robust default first |
| Ambiguous nested containers | Hard debugging | Use container-name in complex structures |
Debugging Container Queries
If a query does not apply:
- verify ancestor has
container-type - inspect actual container width in DevTools
- check if threshold condition is met
- confirm selector and cascade order
- test by temporarily lowering threshold
When debugging, focus on container size, not viewport size.
Mini Exercise
- Create a reusable card component inside two different wrappers (narrow and wide)
- Add
container-type: inline-sizeon each wrapper - Write one
@container (min-width: 500px)rule to switch card layout - Compare behavior in both wrappers at same viewport width
- Add a named container version and verify it still works
FAQ
Are container queries replacing media queries?
No. They solve different scopes. Media queries are viewport-level; container queries are component-level.
Why is my container query never firing?
Most common reason: missing container-type on an ancestor container.
Should every component use container queries?
Not necessarily. Use them where components appear in varying container sizes and need local adaptation.
Is container-name required?
No. It is optional but helpful in complex or nested query contexts.
Can I combine media and container queries together?
Yes, and that is often ideal: global structure with media queries, local component behavior with container queries.