layoutintermediate

Container Query

A CSS feature that lets components respond to their parent container's size rather than the viewport width, enabling truly self-contained and reusable responsive components.

Plain English

Media queries ask "how wide is the browser window?" Container queries ask "how wide is the box I am sitting in?" This sounds like a small distinction, but it changes everything about component design. With media queries, a card component breaks when you move it from a 3-column grid to a sidebar, because the breakpoint was tuned for one context. With container queries, the card detects its own available width and adapts — stack vertically in a narrow sidebar, horizontal layout in a wide grid. You can now build truly portable components: drop the card anywhere, and it figures out how to present itself. This is the reusable component model that CSS has needed for a decade.

Technical

Mark the parent as a containment context: `.card-wrapper { container-type: inline-size; container-name: card; }`. Then query it from inside: `@container card (min-width: 400px) { .card { flex-direction: row; } }`. `container-type: inline-size` enables width-based queries (the most common); `container-type: size` also enables height queries. The `container-name` is optional — unnamed containers still work with anonymous `@container (min-width: ...)`. Units: `cqw` (1% of container width), `cqh` (1% of container height), `cqi` (inline axis), `cqb` (block axis) — use these inside the container for truly fluid sizing. Nesting: a container query can only query its nearest ancestor containment context, not itself. Browser support: all modern browsers as of 2023. Use `@supports (container-type: inline-size)` for progressive enhancement. Common pattern: a single `.card` component file with `@container` rules replacing 3 separate size variants.

Live Demo

Container Queries

The same card component adapts its layout based on its container width — not the viewport width. This is more composable than media queries.

Small (160px)

🎨

Design

Color theory basics

View

Stack layout

Medium (260px)

🎨

Design Systems

Color theory

View topic

Row layout

Large (380px)

🎨

Design Systems

Color

Explore color theory, palettes, and brand systems.

View topic
12 subtopics

Full layout

/* Enable container queries */
.card-wrapper { container-type: inline-size; }

/* Query the container, not viewport */
@container (min-width: 320px) {
.card { flex-direction: row; }
}

Container queries let a component own its responsive logic — no matter where it's placed.

Usage

✓ Good usage

A ProductCard component that uses `@container (min-width: 420px)` to switch from stacked (image above, text below) to horizontal (image left, text right) layout — the same component file works in the homepage hero grid, the search results list, and the sidebar recommendations without any prop variants.

✗ Bad usage

Adding `container-type: inline-size` to every single element on the page "just in case" — containment has a layout cost, and indiscriminate use creates unnecessary compositing boundaries that slow down rendering.

Common mistakes

AI Prompt Example

Copy this into Claude, Cursor, Bolt, or v0.

Convert the Card component to use container queries instead of media queries. Add `container-type: inline-size; container-name: card` to the card wrapper div. Inside the card styles, replace `@media (min-width: 640px)` with `@container card (min-width: 420px)`. Use `cqw` units for the image width so it scales fluidly with the container. The card should stack vertically below 420px container width and go horizontal above it.