CSS Container Queries
For years, responsive design meant media queries: change layout based on the viewport width. But components don't live in the viewport; they live in containers. A product card might sit in a wide main column on one page and a narrow sidebar on another, at the same screen size. Container queries let a component respond to the size (or style) of its container, so the same card rearranges itself correctly wherever it's placed.
Supported in all modern browsers, container queries are one of the biggest shifts in responsive design since media queries themselves. They make design system components genuinely portable, without page-specific overrides.
TL;DR
- Mark an ancestor as a container with
container-type: inline-size(usually), optionally with acontainer-name. - Query it with
@container (min-width: 400px) { … }or@container card (width > 400px). - Descendants respond to the nearest matching container, not the viewport.
- Container query units (
cqi,cqw,cqh,cqmin,cqmax) size things relative to the container. - Style queries (
@container style(--variant: compact)) react to custom property values. - Use media queries for page-level layout and user preferences, and container queries for components.
Quick Example
A card that switches from stacked to horizontal when its container is wide enough:
Drop the same markup into a 300px sidebar and it stacks; in a 700px main column it goes horizontal, on the same screen.
Core Concepts
Establishing Containers
A container query only works against an ancestor that's been declared a container:
container: card / inline-size is shorthand for name plus type. Naming containers lets nested components target a specific ancestor rather than just the nearest one.
Size Queries
The query applies to the container's descendants, not the container itself. To style the container based on its own size, add a wrapper element.
Container Query Units
They're great for fluid typography and spacing inside components: font-size: clamp(1rem, 3cqi + 0.5rem, 2rem). Without a container ancestor, they fall back to the viewport (small viewport units).
Style Queries
Style queries test computed values of custom properties on a container:
They let a parent switch child component variants through a custom property, without extra classes. Custom property style queries are supported in Chromium and Safari, and are arriving in other engines; check support before relying on them. See CSS custom properties.
Containment Side Effects
container-type: inline-size applies inline-size containment: the container's width can't depend on its children's content. Usually harmless for block elements, it can collapse shrink-to-fit containers (floats, inline-blocks, grid or flex items sized by content). If a container suddenly has zero width, give it an explicit or stretching width, or put the container role on a different element.
Container vs Media Queries
They complement each other: media queries shape the page, and container queries let the pieces inside adapt.
Best Practices
Make Layout Wrappers the Containers
Declare containers on layout slots (grid areas, sidebar, main column, card list items) rather than on the component's own root, so components respond to the space they're given and stay portable.
Name Containers in Nested Layouts
Unnamed @container queries target the nearest container ancestor, which may not be the one you expect in nested layouts. Named containers make intent explicit.
Combine With Intrinsic Layout
Grid patterns like repeat(auto-fit, minmax(…)) and Flexbox wrapping handle much of the adaptation. Use container queries for changes intrinsic sizing can't express, like switching a card from stacked to horizontal.
Use Container Units for Fluid Components
Typography and spacing in cqi with clamp() scale smoothly with the component's width, and read better than many discrete breakpoints.
Common Mistakes
Querying Without Declaring a Container
Add container-type: inline-size to an ancestor.
Styling the Container From Its Own Query
A container query can't change the container itself (that would create circular dependencies). Wrap the content in an inner element and style that.
Collapsing Shrink-Wrapped Containers
Putting container-type: inline-size on an element whose width comes from its content (such as a flex item with flex: none) makes it zero-width. Give it a width from its context, or move the container role to a parent.
FAQ
Are container queries supported in all browsers?
Size queries and container query units are supported in all current major browsers (Chrome, Edge, Firefox, and Safari since 2023). Style queries on custom properties have narrower support. Provide sensible default styles that work without the query.
Do container queries replace media queries?
No. Media queries still handle viewport-level layout, user preferences like dark mode and reduced motion, and device capabilities. Container queries handle component-level adaptation. Most modern stylesheets use both.
Do container queries hurt performance?
Containment actually helps the browser limit layout work, and typical use has negligible performance cost. Avoid making thousands of tiny elements containers unnecessarily, and prefer inline-size over size unless you need height queries.
How do container queries work with Tailwind?
Tailwind v4 includes container query support natively: mark containers with @container (or named @container/card) and use variants like @md:flex-row or @lg/card:grid-cols-2. See Tailwind.
Related Topics
- CSS — The styling language overview
- Responsive Design — Adapting layouts across contexts
- CSS Grid — Intrinsic responsive layouts
- CSS Custom Properties — Driving style queries
- Design Systems — Portable components
- Web Components — Encapsulated, reusable components