Container query

On this page 7

A container query is a CSS feature that applies styles based on the dimensions or computed style of an ancestor element, called the container, instead of the dimensions of the browser viewport. In CSS it is written with the @container at-rule and enables component-level responsive design: a card, widget or navigation block adapts to the space it actually receives.

Media queries answer how wide the screen is; container queries answer how wide the box is that this component sits in. The difference matters because the same component may appear in a narrow sidebar and a wide main column on the same page at the same time, where a viewport-based rule cannot style both correctly.

How container queries work

Using a container query takes two steps. First, an ancestor is declared a query container with the container-type property, optionally named with container-name. Second, descendant rules are wrapped in an @container block with a condition, such as @container card (min-width: 400px), and apply only when the nearest matching container meets it.

Declaring a container applies size containment: the browser lays out the container without considering its children’s size along the queried axis. This breaks the circular dependency in which a child’s styles change the container’s size, which in turn changes which styles apply. It is also why a container cannot query its own size to style itself, only its descendants.

ValueQueryable featuresContainment effectTypical use
inline-sizeInline size, usually widthInline-axis size containmentMost components, the default choice
sizeWidth, height and aspect ratioContainment on both axesElements with an explicit height
normalStyle queries onlyNo size containmentDefault value of every element
Values of the container-type property

Because size contains both axes, an element with container-type: size and no explicit height collapses to zero height. For this reason, inline-size is the practical default in almost all layouts.

Size queries, style queries and container units

The @container rule supports several kinds of conditions. Size queries test dimensions and are the most widely used. Style queries test computed values, currently most reliably the values of custom properties, such as whether a theme variable equals dark. Newer scroll-state queries test conditions such as whether a sticky element is stuck.

Query kindExample conditionSupport status
Size query(min-width: 30em) or (width > 400px)Supported in all major browsers since 2023
Style querystyle(--variant: compact)Supported for custom properties, less uniform
Scroll-state queryscroll-state(stuck: top)Newer, limited support
Kinds of container query conditions

Container query length units size values relative to the query container: cqw and cqh are 1% of its width and height, cqi and cqb are 1% of its inline and block size, and cqmin and cqmax use the smaller or larger dimension. Combined with clamp(), these units allow fluid typography that scales with the component rather than with the screen.

Container queries compared with media queries

Container queries complement media queries rather than replace them. Media queries still handle page-level layout and user preferences, while container queries handle how individual components respond to their slots.

AspectContainer queryMedia query
Condition based onAncestor container size or styleViewport and device features
ScopeIndividual componentsWhole page layout
Setup requiredDeclaring a containerNone
User preferencesNot availableprefers-color-scheme, prefers-reduced-motion
Reuse across contextsComponent adapts anywhereSame rules regardless of slot
Containment side effectsYes, size containmentNone
Container query and media query compared

A useful division of labor is: media queries define the page grid, for example how many columns exist at a breakpoint, while container queries define component variants, for example whether a card shows its image beside or above the text. Layout tools such as CSS grid and flexbox work inside both approaches.

Practical patterns for container queries

Container queries are most valuable in design systems and component libraries, where authors cannot know every place a component will be used. The table maps common situations to an appropriate pattern.

SituationRecommended approachReason
Card reused in sidebar and main areaSize query on a wrapperLayout follows available width
Overall page columnsMedia queryDepends on the viewport
Theme or variant switchStyle query on a custom propertyAvoids extra modifier classes
Heading size within a widgetcqi units with clamp()Scales smoothly with the widget
Simple wrapping list of itemsFlexbox or grid auto-fitIntrinsic layout needs no query
Choosing when to use a container query

A reliable convention is to place the container on a dedicated wrapper around the component, not on the component itself. This keeps containment side effects predictable and lets the component query the space it has been given.

Limitations and common mistakes

Container queries introduce new failure modes that developers used to media queries often miss. Most stem from misunderstanding size containment.

  • Querying the container itself: styles inside @container apply to descendants only, never to the container element.
  • Collapsed height: container-type: size without an explicit height removes intrinsic height.
  • Shrink-to-fit parents: containers inside floats or inline-block parents may size unexpectedly because content no longer drives width.
  • Unnamed nested containers: without container-name, a query matches the nearest ancestor container, which may not be the intended one.
  • Over-querying: many layouts adapt naturally with intrinsic grid and flexbox, without any query.

A plain-language summary

A container query lets a piece of a web page adjust to the box it sits in, not to the whole screen. Think of a piece of furniture that rearranges itself to fit whichever room it is placed in.

Before container queries, designs could only react to the size of the entire browser window. Now a product card can look one way in a narrow side column and another way in a wide area. The card decides based on its own space.

An example from practice

A news site uses one article teaser component in three places: a wide homepage lead slot, a three-column grid and a narrow sidebar about 300 px wide. With media queries alone, the sidebar teasers inherited the desktop layout and squeezed their images to unreadable thumbnails.

The front-end team wraps each teaser in an element with container-type: inline-size and a container name of teaser. Below 350 px of container width, the teaser stacks its image above a short headline; between 350 and 600 px it places a small image beside the text; above 600 px it shows a large image, summary and author line. Headline size uses clamp() with cqi units.

The same component now renders correctly in every slot without page-specific overrides, and about 120 lines of context-specific CSS are deleted.