CSS Container Style Queries for Computed Styles

CSS container queries extend beyond viewport and dimensional constraints, allowing developers to query the computed styles of an ancestor element using the style() functional notation. This article explains the mechanics of CSS container style queries, how they evaluate computed values such as custom properties without measuring layout dimensions, and how to implement them effectively in modern web development.

Understanding the style() Query Function

Standard container queries evaluate geometric dimensions like width or inline-size using container-type: inline-size. In contrast, style queries evaluate the computed CSS property values of a container element. They use the @container style(...) syntax to apply conditional styles to descendant elements.

Because style queries inspect computed values rather than layout geometry, they do not require dimensional containment (contain: size or container-type: size). Consequently, any element can serve as a style container without causing the layout reflow constraints associated with size containment.

Syntax and Basic Usage

To query an element's style, you wrap the target property and value inside the style() function within an @container rule.

/* Container declaration */
.card-wrapper {
  container-name: card;
  --theme: dark;
}

/* Querying computed styles */
@container card style(--theme: dark) {
  .card-content {
    background-color: #121212;
    color: #ffffff;
  }
}

In this example, whenever .card-wrapper computes --theme as dark, .card-content receives the dark mode rules. The query succeeds regardless of the container's physical pixel width or height.

If a container-name is omitted, the query checks the nearest ancestor that matches the queried style condition:

@container style(--variant: highlighted) {
  p {
    font-weight: bold;
  }
}

How Computed Values Are Evaluated

Container style queries evaluate computed values, not declared or author-specified syntax. This distinction is critical for how properties are matched:

  1. Relative Units are Resolved: If a container defines font-size: 2rem, and the browser resolves that to 32px, a query targeting style(font-size: 32px) resolves to true.
  2. Color Normalization: Colors are converted to their computed forms (such as srgb or rgb()), meaning queries match against the resolved color rather than the specific keyword or hex code used in the declaration.
  3. Custom Properties (CSS Variables): The primary implementation across modern browsers targets custom properties. Custom properties retain their exact string value once computed, making them reliable identifiers for state management (e.g., --status: active, --layout: compact).

Why Dimension Checks Are Bypassed

Size queries require the browser to apply layout containment to prevent infinite layout loops—where a query modifies an element's size, triggering another query re-evaluation.

Style queries do not alter the box model hierarchy in the same loop-prone manner when scoped to custom properties or non-layout-dependent styles. The browser evaluates the cascade, computes property values down the DOM tree, and resolves the @container style() rules during the standard style computation phase, well before the layout phase calculates pixel dimensions.

Current Implementation and Browser Support

The CSS Cascading and Style Sheets Level 5 specification defines style queries for both standard CSS properties (e.g., style(color: blue)) and custom properties (e.g., style(--variant: alert)).

Currently, browser support primarily focuses on custom properties. Querying custom properties provides a declarative alternative to managing numerous BEM modifier classes or data attributes, enabling components to adapt autonomously based on context passed down through CSS variables.