skip to content

What is a CSS style query written as @container style(--variant: promo), and how does it differ from a size container query?

level: middleimportance: nice to knowfreq 20%

answer

  1. same at-rule, value instead of size
  2. no container-type needed here
  3. custom properties only in practice
  4. parent publishes intent, children decide
  5. descendants still, never the container

basics

~20 s

A style query tests the computed value of a property on the query container rather than the container's size. Every element is a style query container by default, so no container-type declaration is needed, and shipping browsers currently support only custom properties in the condition.

solid answer

~50 s

A style query uses the same `@container` at-rule but replaces the size condition with a `style()` function that tests a **computed value** on the query container: `@container style(--variant: promo) { … }`. Two things make it behave differently from a size query. First, no opt-in is needed — every element is a style query container by default, so `container-type` is irrelevant here; the query resolves against the nearest ancestor, or the nearest one carrying the given `container-name`. Second, what it tests is a value, not a measurement. The typical use is letting a parent set `--variant: promo` and having descendant components restyle themselves without a modifier class threaded through every child. Support today covers custom properties in current Chrome, Safari and Firefox; querying standard properties such as `display` is specified but not shipped, so treat it as custom-properties-only in production. The no-self-query rule still applies: the styles land on descendants.

code

css · 15 lines
css
.promo-region {
  --variant: promo;
}

.card {
  background: canvas;
  border: 1px solid currentColor;
}

@container style(--variant: promo) {
  .card {
    background: gold;
    border-width: 2px;
  }
}

go deeper

for a junior

Know that @container has a second form, style(), that tests a value such as a custom property on an ancestor instead of testing that ancestor's size.

for a middle

Explain why no container-type declaration is needed for style queries, and show the pattern where a region sets an inherited custom property and descendants branch on it.

for a senior

Be precise about what actually ships — custom properties only — and give a defensible rule for when an inherited signal beats a modifier class in a real component library.

for a principal

Own the theming contract: which custom properties are the public signal between regions and components, and how that decision keeps components decoupled from the pages that host them.

## The same at-rule, a different question `@container` supports two kinds of condition. A **size query** asks how big the container is: `@container (min-width: 400px)`. A **style query** asks what a property computes to on the container: `@container style(--variant: promo)`. Both resolve against a query container in the element's ancestor chain, and in both cases the rules inside style that container's **descendants**, never the container itself. ```css .promo-region { --variant: promo; } @container style(--variant: promo) { .card { background: var(--promo-bg); border-color: var(--promo-border); } } ``` Any descendant `.card` inside an element whose computed `--variant` is `promo` picks up the promo styling. Because custom properties inherit, setting `--variant` once at a region boundary reaches everything below it. ## No opt-in required This is the difference people miss. A size query needs `container-type: inline-size` or `size`, because the browser needs a containment promise to resolve the measurement without circularity. A style query has no such problem — it reads a computed value, which is already settled — so **every element is a style query container by default**. `container-type: normal`, the default, still allows style queries. There is no `container-type: style` value; if you write one, the declaration is invalid. Names still work the same way. `container-name` on an ancestor plus `@container theme style(--variant: promo)` lets you target a specific ancestor rather than the nearest one. ## What can go inside style() The specification allows querying declared property values generally, but browser implementations shipped the custom-property case first and that is the only part you can rely on today. In practice: - `style(--variant: promo)` — supported; tests whether the container's computed `--variant` equals `promo`. - `style(--variant)` — supported as a test for whether the custom property has a usable value at all. - `style(display: flex)` or `style(font-weight: bold)` — specified, but **not shipped** in browsers as of 2026. Do not build on it. Conditions combine with `and`, `or` and `not`, and a single `@container` rule can carry a name plus both a size condition and a style condition. ## Why this is useful The pattern it replaces is the modifier-class cascade. Without style queries, a themed region means either descendant selectors that couple every component to the region (`.promo-region .card { … }`), or a modifier class threaded down through every child in the template. With a style query, the region sets one inherited custom property and each component decides for itself what that means — the component keeps its own styling rules, and the parent only publishes intent. It also composes well with custom properties used as plain values. A component can consume `var(--variant)` for a colour *and* branch on `style(--variant: promo)` for a structural change that no single value could express, such as switching from a row to a column layout. ## Limits worth stating in an interview - **No self-query.** A container's own `--variant` does not restyle the container; only its descendants. To style the region itself, write a normal rule on it. - **Custom properties only, today.** Standard-property style queries are specified but unshipped; claiming otherwise is a correctness error. - **Equality, not computation.** `style(--variant: promo)` compares computed values; it is not a general expression language, and there is no numeric comparison for custom properties in shipping implementations. - **A class is often simpler.** If a component's parent already sets a class, a plain class selector is clearer and needs no explanation. Style queries pay off when the signalling value is inherited across an arbitrary depth and the intermediate markup is not yours to change. ## Feature detection Because support is more recent than size queries, feature-detect when the difference matters: ```css @supports (container-type: inline-size) { /* size queries are safe */ } ``` For style queries specifically, the pragmatic approach is progressive enhancement: express the default appearance in ordinary rules and let the style query add the variant, so a browser that ignores it renders the base treatment rather than a broken one.

  • Why does a style query need no container-type while a size query does?
    A size query has to measure the container, and measuring an element whose size could depend on the styles being applied is circular — containment is the promise that removes the circularity. A style query reads a computed value that is already resolved, so no containment is needed, and every element is a style query container by default.
  • Can a style query test a standard property such as display or font-size?
    The specification allows it, but browsers as of 2026 have only shipped the custom-property case. Treat `style()` as custom-properties-only in production code; a condition on a standard property will not match anywhere you can currently ship, so building a layout on it is a correctness risk rather than a progressive enhancement.
  • When is a plain modifier class the better choice over a style query?
    Whenever the parent that knows the variant is also the code that renders the component. A class is more obvious to a reader and needs no feature-detection story. Style queries earn their place when the signal must travel through markup you do not control, or across an arbitrary nesting depth, where an inherited custom property is the only clean channel.

saying these in an interview costs you the question

  • Says style queries need container-type: style on the container
  • Claims style(display: flex) works in shipping browsers today
  • Expects the container itself to be restyled by its own style query
  • Thinks style() can do numeric comparisons on custom properties
  • Treats style queries as a replacement for all modifier classes

context