# The End of Media Queries? Introduction to Container Queries

> Media queries respond to the viewport. Container queries respond to the parent container.

Media queries respond to the viewport. A card inside a 200px sidebar on a 4K monitor still sees a 4K screen.

```css
@media (min-width: 768px) {
  .card {
    display: flex;
  }
}
```

This works for page layouts. For component libraries, the component has no way to know how much space it has.

## The problem: context awareness

Imagine a "Product Card" component.

- On the homepage, it occupies the full width. Simple.
- In a sidebar, it's squeezed into a narrow column.
- Inside a dashboard widget, it's medium-sized.

If you rely on `@media` queries, the card only knows how wide the _screen_ is. It has no idea it's squished inside a tiny sidebar on a massive 4k monitor.

## The solution: container queries

**Container Queries** allow us to style an element based on the available space within its _container_, not the viewport.

### Step 1: define the container

First, you tell the parent element that it is a container.

```css
.card-wrapper {
  /* Define this element as a query container */
  container-type: inline-size;
  container-name: card-container;
}
```

- `container-type: inline-size`: We want to query the width (most common).
- `container-name: card-container`: Optional, but good practice. It allows us to target this specific container explicitly.

![Portling flipping a card between stacked and side-by-side as its box resizes](../static/uploads/css-container-queries-01-container-flip.png)

### Step 2: query the container

Now, inside your component, you query that container.

```css
.card {
  display: flex;
  flex-direction: column;
}

/* When the container is wider than 400px */
@container card-container (min-width: 400px) {
  .card {
    flex-direction: row; /* Switch to horizontal layout */
    align-items: center;
  }

  .card-image {
    width: 50%;
  }
}
```

Try it below. Drag the corner of the demo box and watch the same card flip between its stacked and side-by-side layouts. Your viewport never changes, only the container does.

<div class="cq-demo"></div>

Prefer to poke at the code yourself? Edit the CSS below, press Apply, then drag the preview's edge. The card flips layouts while your viewport never moves.

<!-- live-preview: Product card -->

```html
<div class="demo-stage">
  <article class="card">
    <div class="card-image" aria-hidden="true"></div>
    <div class="card-body">
      <h3 class="card-title">Trailhead Backpack</h3>
      <p class="card-text">40L, weatherproof, lifetime repairs.</p>
      <p class="card-price">$129</p>
    </div>
  </article>
</div>
```

```css
.demo-stage {
  container-type: inline-size;
  container-name: demo;
  background: #f5f5f5;
  padding: 1rem;
  border-radius: 0.75rem;
}
.card {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  background: #fff;
  border: 1px solid #e5e5e5;
  border-radius: 0.75rem;
  padding: 1rem;
}
.card-image {
  min-height: 120px;
  border-radius: 0.5rem;
  background: linear-gradient(135deg, #84cc16, #15803d);
}
.card-title {
  margin: 0;
  font-size: 1.1rem;
}
.card-text {
  margin: 0.25rem 0;
  color: #525252;
}
.card-price {
  margin: 0;
  font-weight: 700;
}
@container demo (min-width: 400px) {
  .card {
    flex-direction: row;
    align-items: center;
  }
  .card-image {
    width: 40%;
    align-self: stretch;
  }
}
```

<!-- /live-preview -->

### New units: the "fluid" typography dream

Container Queries brought new CSS units that are relative to the container's size, similar to how `vw` is relative to the viewport.

- `cqw`: 1% of a query container's width
- `cqi`: 1% of a query container's inline size (logical width)
- `cqh`: 1% of a query container's height
- `cqmin` / `cqmax`: Smaller/Larger of cqi and cqb

This is perfect for fluid typography that scales with the component, not the screen.

```css
.card-title {
  /* Title is always 5% of the card's width */
  font-size: 5cqi;
}
```

## Advanced: style queries (experimental)

We can also query the _computed style_ of a container, not only its size.

```css
@container style(--theme: dark) {
  .card {
    background: black;
    color: white;
  }
}
```

_Note: Style queries have varying browser support compared to Size queries._

## Implementation strategy

Container Queries let components own their breakpoints.

1. **True Portability**: You can drag-and-drop that `.card` into a 3-column grid, a sidebar, or a modal. It will "look at itself", realize how much space it has, and adapt automatically.
2. **Decoupling**: The page layout developer doesn't need to know the inner breakpoints of the card.

## Browser support

As of 2026, Container Queries (`@container`) and units (`cqi`/`cqw`) are supported in **all major evergreen browsers** (Chrome, Firefox, Safari, Edge).

## Conclusion

Media queries still work for global page layouts. For individual UI elements, Container Queries are the better tool. They respond to available space, not screen dimensions.