liveBook · Manning

Container style query

As explained in CSS in Depth, Second Edition

The CSS style() function expresses a container-query condition based on the computed value of a custom property on the query container.

A reusable component may need different styles in different places, even when the viewport stays the same size. A container style query lets a descendant respond to a custom property on an ancestor, rather than tying its styles to a particular page layout or viewport width. section 10.0 section 10.4.1

@container style(--color-theme: dark) {
  /* conditional styles */
}

Use @container style(--color-theme: dark) to apply the enclosed rules when the query container has that custom-property value. Unlike a container size query, a style query does not require you to explicitly establish a size container. section 10.4

Listing 10.7 Using a container style query to change module layout
@layer layout {
  .l-page > aside {
    --sidebar: true;    #1
  }
}

@layer modules {
  @container style(--sidebar: true) {    #2
    .race-detail {
      margin-block: 1em;
      display: flex;
    }

    .race-detail > img {
      flex: 0 0 30cqi;
    }

    .race-detail__body > h3 {
      margin-block-start: 0;
    }
  }
}

For a card in a sidebar, the layout sets --sidebar: true. The module layer queries that value, then switches the card to flexbox, sizes its image with a container-relative unit, and adjusts spacing. The card’s rules do not need to name the sidebar selector. section 10.4.1

That separation matters when the same module appears in another layout. A selector that names its current page and sidebar would need another selector for each new context, increasing coupling and specificity. Set a meaningful custom property on the context instead, and let the module respond to it. section 10.4.1

Listing 10.8 Enabling dark mode via a custom property
@layer base {
 :root {
    --color-theme: light;                 #1
  }
  @media (prefers-color-scheme: dark) {
    :root {
      --color-theme: dark;               #1
    }
  }
  [data-theme="light"] {          #2
    --color-theme: light;
  }
  [data-theme="dark"] {          #2
    --color-theme: dark;
  }

  @container style(--color-theme: dark) {   #3
    body {
      background-color: #555;
      color: white;
      color-scheme: dark;
    }
  }
}

A color-theme property can likewise collect several decisions into one condition: prefers-color-scheme sets the initial value, a data-theme attribute can override it, and the style query applies the dark rules. JavaScript-controlled buttons can change the attribute without duplicating those rules. section 10.4.2

Use style queries when a custom property is a useful signal for contextual styling, particularly for reusable modules or rules triggered in several ways. Check browser support before relying on them: as of mid-2024, support was present in Chrome and Edge but not Firefox or Safari, making progressive enhancement the safer use. section 10.4.1 section 10.4

How CSS in Depth, Second Edition covers it

How deep it goes
Defines style() syntax and works through sidebar and dark-mode applications, without exploring browser implementation internals.
Examples
Uses a sidebar card that changes layout and a light/dark theme selected through system preference or HTML attributes.
What it assumes
Assumes familiarity with CSS selectors and custom properties while introducing style-query syntax and its lack of an explicit size-container requirement.
What you can do after
Build it from scratch by setting a contextual custom property and applying descendant styles through @container style().
How it connects
Connects CSS custom properties with container queries, modular CSS, media queries, cascade layers, and dark-mode controls.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of CSS in Depth, Second Edition. The section links point to the parts of the book it draws on.