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, %) with min-width, max-height, aspect-ratio, and orientation.
  • 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, not enable 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 to writing-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

FeatureChrome/EdgeFirefoxSafariNotes
container-type: inline-size105+110+16+Widely supported, safe for production
container-type: size105+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+Pending18+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

IssueRoot CauseResolution
Layout thrashing on resizeApplying size containment to deeply nested or frequently repainted elementsDefault to inline-size. Use size only when block dimension directly impacts internal layout.
Fallback chains override container stylesMissing @supports nesting or incorrect cascade orderWrap CQs in @supports, place baseline styles outside, and use higher specificity or !important sparingly if needed.
Inconsistent behavior in vertical writing modesConfusing width/height with logical inline/block axesUse cqi/cqb and inline-size/block-size for writing-mode agnostic layouts.
Global layout shifts instead of component adaptationsOverusing CQs for page-level routing or major structural changesReserve CQs for component-level micro-adaptations. Use media queries for global layout shifts.
Ambiguous matches in nested treesMissing container-name when multiple containers share the same typeAlways 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

  1. Inspect Containment Context: Open Chrome/Firefox DevTools → Elements panel. Select the container element. In the Computed tab, verify container-type and container-name are applied.
  2. Visualize Query Boundaries: In Chrome DevTools, enable Show container query boundaries in the Layout pane (under Elements > Styles > Container Queries). This overlays a visual guide showing where cqw/cqi calculations originate.
  3. Simulate Container Resize: Use the Device Toolbar or manually drag the container's parent in the Elements panel. Observe @container breakpoints triggering in the Styles pane.
  4. Debug Style Queries: Toggle custom properties in the Styles panel. DevTools will highlight which @container style(...) blocks activate based on computed values.
  5. Performance Profiling: Open Performance tab → Record → Resize container repeatedly. Check for Layout spikes. If present, switch from size to inline-size containment 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 @container syntax, 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.