container-type / @container

Container Queries

Media queries respond to the viewport. Container queries respond to the box the component is actually in, so one card works in a narrow sidebar and a wide main column without a wrapper class for each.

Mission log

Same component, three layouts

This card doesn’t know about the viewport. It only reacts to the width of the box it sits in, so it looks right in a sidebar, a modal, or a full-width section without a single extra class.

Logged 6 hours ago · 384,400km · lunar orbit

The CSS

Copied
.container {
  container-type: inline-size;
  container-name: demo-card;
}

.card {
  display: flex;
  flex-direction: column;

  @container demo-card (min-width: 380px) {
    flex-direction: row;
  }
}

.title {
  font-size: clamp(1rem, 5.2cqi, 1.3rem);
}

How it works

Mark an ancestor as a query container with container-type: inline-size, and name it with container-name if you like. Anything inside can then use @container (min-width: 380px) instead of @media, measured against the container’s box rather than the window.

Container query length units are useful too: cqi is a percentage of the container’s inline size, so the heading scales with the card. A vw unit could never do that for a component that isn’t full width.

Widely supported

Chrome / Edge105+Safari16+Firefox110+
:has() · tic-tac-toe

turns, wins and reset, all CSS

@property · counter()
hover me
cos() · sin()

trigonometry, in CSS

:has() quantity query

switch guests on