CSS @container At-Rule

The @container at-rule applies CSS styles based on conditions associated with a containing element. Unlike media queries, which commonly respond to the viewport, container queries allow components to adapt to the space and context provided by their containers.

@container Syntax

@container (min-width: 400px) {
  .card {
    display: flex;
  }
}

The @container rule contains a condition followed by a block of CSS rules. The rules apply when a matching ancestor container satisfies the condition.

A container query can include a container name, a condition, or both. Conditions can use logical operators such as and, or, and not.

For size queries, the container must be established using the container-type property or the container shorthand.

How @container Works

Container queries allow an element to respond to its containing element rather than relying only on the browser window's dimensions.

For example, a card can display its content vertically in a narrow container and switch to a horizontal layout when the container becomes wider.

First, establish a query container. Then use @container to define styles that apply when the container meets a specified condition.

.card-wrapper {
  container-type: inline-size;
}
.card {
  display: block;
}
@container (min-width: 400px) {
  .card {
    display: flex;
  }
}

The .card element changes to a flex layout when its eligible ancestor query container is at least 400px wide.

The query styles apply to descendants of the container, not directly to the queried container itself.

Container Types

The container-type property establishes the type of queries an element can support.

Value Description
normal Does not establish a size query container. The element can still participate in applicable style queries.
inline-size Enables size queries along the inline axis, commonly the horizontal direction.
size Enables size queries along both the inline and block axes and applies size containment.
scroll-state Establishes a container for scroll-state queries. Support varies by browser.

For most responsive component layouts, inline-size is a practical choice because it allows the component to respond to its available width without requiring containment along both axes.

Named Containers

The container-name property assigns a name to a query container. This allows an @container rule to target a particular container instead of relying only on the nearest eligible ancestor.

.sidebar {
  container-type: inline-size;
  container-name: sidebar;
}
@container sidebar (min-width: 300px) {
  .sidebar-card {
    display: flex;
  }
}

The rule applies to matching descendants when an eligible ancestor named sidebar is at least 300px wide.

You can also use the container shorthand to define the name and type together.

.sidebar {
  container: sidebar / inline-size;
}

Style Queries

Style queries test computed style information on an ancestor container. The style() notation is used inside @container to define the condition.

A common use is checking the value of a CSS custom property.

.theme-wrapper {
  --theme: dark;
}
@container style(--theme: dark) {
  .theme-card {
    background-color: #222;
    color: #fff;
  }
}

The styles apply when the queried ancestor has a computed --theme value of dark.

Custom property style queries are supported in modern browsers, but support for querying ordinary CSS properties remains limited.

Scroll-State Queries

Scroll-state queries allow styles to respond to scrolling conditions, including whether an element is stuck in a sticky position, is snapped into place, or can be scrolled in a particular direction.

Use container-type: scroll-state to establish an appropriate query container.

.sticky-header {
  position: sticky;
  top: 0;
  container-type: scroll-state;
}
@container scroll-state(stuck: top) {
  .header-content {
    background-color: #eee;
  }
}

In supporting browsers, the background of .header-content changes when its sticky container becomes stuck at the top of the scrollport.

Scroll-state queries have more limited browser support than container size queries.

@container Example

The following example demonstrates a card that changes its layout when the width of its container reaches 240px. The container uses container-type: inline-size so the card responds to the available space.

.card-wrapper {
  width: 280px;
  max-width: 100%;
  container-type: inline-size;
}
.card {
  padding: 12px;
  border: 1px solid #ccc;
  background-color: #f5f5f5;
}
.card-title {
  font-weight: bold;
  margin-bottom: 8px;
}
.card-description {
  margin: 0;
}
@container (min-width: 240px) {
  .card {
    display: flex;
    align-items: center;
    gap: 12px;
  }
  .card-title {
    margin-bottom: 0;
  }
}

At widths below 240px, the title appears above the description. At widths of 240px or more, the two appear side by side.

Play in Editor

Browser Support

Container size queries are widely available in modern browsers. Style queries and scroll-state queries have separate compatibility requirements. Visit Can I Use? and search for CSS container queries to check current support.

Specifications

The @container at-rule is defined in the CSS Conditional Rules Module Level 5 specification, with container query behavior also described in the CSS Containment specifications.

CSS Conditional Rules Module Level 5