Container Query Syntax Basics
Container Query Syntax Basics
Modern component-driven architecture demands a shift from viewport-centric breakpoints to element-aware contexts. This guide breaks down the foundational Container Query Syntax Basics for building truly modular interfaces. By establishing containment directly on UI elements, you can decouple component styling from global layout shifts and ship self-contained, reusable modules. We’ll cover the core @container at-rule, container-type and container-name properties, and the new relative units that power responsive micro-interactions.
Key Implementation Points:
- Understanding the paradigm shift from viewport to component-level responsiveness
- Establishing containment contexts without breaking layout flow
- Writing spec-compliant size and style queries
- Leveraging container-relative units for scalable UI components
Declaring the Containment Context
To query an element, you must first establish a containment context on its direct ancestor. The container-type property dictates which dimensions the browser tracks, directly impacting rendering performance and query accuracy.
container-type: inline-size: Tracks only the inline axis (width in horizontal writing modes). Highly performant, as it avoids block-size layout recalculations and is the recommended default.container-type: size: Tracks both inline and block dimensions. Triggers more frequent layout recalculations; reserve for components where height directly dictates internal layout.container-name: Assigns an explicit identifier. Crucial for targeting specific containers in deeply nested DOM trees where multiple containment contexts exist.- Ancestor Rule: Containment must be declared on a direct or indirect parent of the queried element. The browser resolves queries up the DOM tree until it finds a matching named or typed container.
When deciding between viewport and element-level responsiveness, understanding the Container vs media queries comparison clarifies when containment prevents unnecessary layout thrashing.
/* Minimal DOM structure for context */
/* <div class="card-wrapper"><div class="card-content">...</div></div> */
.card-wrapper {
container-type: inline-size;
container-name: card;
}
@container card (min-width: 400px) {
.card-content {
display: grid;
grid-template-columns: 1fr 2fr;
gap: 1.5rem;
}
}
The @container At-Rule Structure
Once a context is established, conditional styling follows a strict, spec-compliant syntax. The @container at-rule evaluates either physical dimensions or computed CSS values, enabling highly granular component logic.
- Standard Syntax:
@container <name> (<condition>) { ... } - Size Conditions: Use standard length units (
px,rem,%) withmin-width,max-height,aspect-ratio, andorientation. - Style Queries: Evaluate custom properties (
--theme,--spacing) and computed values. Ideal for theme switching, accessibility states, and component variants without JavaScript. - Logical Operators:
and,or,notenable complex condition grouping. Always group conditions logically to improve readability and maintainability.
Structuring queries this way aligns directly with scalable Responsive Component Patterns in production workflows.
/* Style Query: Evaluates computed custom property */
@container style(--theme: dark) {
.component {
background: #1a1a1a;
color: #f0f0f0;
border-color: #333;
}
}
/* Complex Size Query with Logical Operators */
@container card (min-width: 300px) and (max-width: 600px) {
.component-header {
flex-direction: column;
align-items: flex-start;
}
}
Container Query Units & Relative Sizing
Container-relative units replace static px or rem values with dynamic scaling factors tied directly to the containment context. These units enable proportional spacing, typography, and micro-interactions that adapt fluidly to available space.
cqw/cqh: 1% of container inline/block size.cqi/cqb: Logical equivalents that adapt towriting-mode(critical for RTL/vertical layouts).cqmin/cqmax: Selects the smaller or larger dimension, perfect for responsive padding, border radii, and icon scaling.
Pairing these units with fluid scaling techniques like Fluid Typography with clamp() creates self-adjusting components that scale proportionally without hard breakpoints.
.component-title {
/* Fluid typography scaling between 1rem and 2.5rem based on container width */
font-size: clamp(1rem, 2cqw + 0.5rem, 2.5rem);
/* Logical spacing that adapts to container dimensions */
padding: 1cqi;
margin-block: 0.5cqb;
border-radius: min(1rem, 2cqmin);
}
Production-Ready Syntax & Progressive Enhancement
Deploying container queries requires robust progressive enhancement. Wrap your syntax in @supports (container-type: inline-size) to ensure graceful degradation. Provide baseline styles outside the block, and optionally chain @media queries for legacy browsers. Avoid containment conflicts by ensuring container declarations don't interfere with CSS Grid/Flexbox intrinsic sizing. Modern linters (Stylelint, PostCSS) support container query validation out-of-the-box. For deployment guidelines, refer to How to use container queries in production.
/* Progressive Enhancement Pattern */
@supports (container-type: inline-size) {
.card {
container-type: inline-size;
padding: 1rem;
}
@container (min-width: 300px) {
.card { padding: 2rem; }
}
}
@supports not (container-type: inline-size) {
/* Baseline fallback for unsupported browsers */
.card { padding: 1rem; }
@media (min-width: 600px) {
.card { padding: 2rem; }
}
}
Browser Compatibility Matrix
| Feature | Chrome/Edge | Firefox | Safari | Notes |
|---|---|---|---|---|
container-type: inline-size | 105+ | 110+ | 16+ | Widely supported, safe for production |
container-type: size | 105+ | 110+ | 16+ | Supported, but monitor layout performance |
Container Query Units (cqw, cqi, etc.) | 105+ | 110+ | 16+ | Fully supported across modern engines |
Style Queries (@container style(...)) | 111+ | Pending | 18+ | Partial support; use @supports feature detection |
Cross-Browser Note: Inline-size containment is stable across all major engines. Full size containment and style queries require progressive enhancement strategies. Always test with @supports before shipping style-dependent logic.
Common Implementation Pitfalls & Fixes
| Issue | Root Cause | Resolution |
|---|---|---|
| Layout thrashing on resize | Applying size containment to deeply nested or frequently repainted elements | Default to inline-size. Use size only when block dimension directly impacts internal layout. |
| Fallback chains override container styles | Missing @supports nesting or incorrect cascade order | Wrap CQs in @supports, place baseline styles outside, and use higher specificity or !important sparingly if needed. |
| Inconsistent behavior in vertical writing modes | Confusing width/height with logical inline/block axes | Use cqi/cqb and inline-size/block-size for writing-mode agnostic layouts. |
| Global layout shifts instead of component adaptations | Overusing CQs for page-level routing or major structural changes | Reserve CQs for component-level micro-adaptations. Use media queries for global layout shifts. |
| Ambiguous matches in nested trees | Missing container-name when multiple containers share the same type | Always assign explicit container-name values in complex component hierarchies. |
Frequently Asked Questions
What is the difference between container-type: inline-size and container-type: size?inline-size establishes a query context based only on the inline dimension (width in horizontal writing modes), which is highly performant. size establishes a context for both inline and block dimensions but triggers more frequent layout recalculations, making it less suitable for frequently resized elements.
Can I use container queries with CSS Grid and Flexbox? Yes. Container queries work seamlessly with Grid and Flexbox. Declare the containment context on a parent element, and queried children can adjust their internal grid/flex layouts based on the container's dimensions rather than the viewport.
How do I handle browsers that don't support container queries?
Wrap your container query syntax in an @supports (container-type: inline-size) block. Provide a baseline layout outside the block, and optionally use @media queries as a fallback for viewport-based responsiveness in older browsers.
When should I use style queries instead of size queries? Use style queries when component appearance depends on computed CSS properties, custom properties, or inherited states rather than physical dimensions. They are ideal for theme switching, accessibility preferences, and state-driven UI variations.
DevTools Debugging Workflow
- Inspect Containment Context: Open Chrome/Firefox DevTools → Elements panel. Select the container element. In the Computed tab, verify
container-typeandcontainer-nameare applied. - Visualize Query Boundaries: In Chrome DevTools, enable
Show container query boundariesin the Layout pane (under Elements > Styles > Container Queries). This overlays a visual guide showing wherecqw/cqicalculations originate. - Simulate Container Resize: Use the Device Toolbar or manually drag the container's parent in the Elements panel. Observe
@containerbreakpoints triggering in the Styles pane. - Debug Style Queries: Toggle custom properties in the Styles panel. DevTools will highlight which
@container style(...)blocks activate based on computed values. - Performance Profiling: Open Performance tab → Record → Resize container repeatedly. Check for
Layoutspikes. If present, switch fromsizetoinline-sizecontainment or debounce JS-driven resizes.
Specification References
- CSS Containment Module Level 3: Defines
container-type,container-name, and containment semantics. W3C Spec - CSS Conditional Rules Module Level 5: Standardizes
@containersyntax, logical operators, and style query evaluation. W3C Spec - CSS Values & Units Module Level 4: Documents container-relative units (
cqw,cqh,cqi,cqb,cqmin,cqmax). W3C Spec
Related articles
More pages in the same section.