CSS

CSS Container Queries in 2026: What They Are and When to Use Them

By Ken Key Mar 3, 2026 4 min read Updated Oct 16, 2026

CSS Container Queries in 2026: What They Are and When to Use Them
The short answer

A CSS container query styles an element based on its parent container's size, not the viewport. You set container-type on the parent, then write @container rules for the children. Use them for reusable components like cards or nav items. Use media queries for page-level layout.

Part of the complete web design guide.

On this page

A container query lets a component change its styles based on the size of its parent container instead of the browser viewport. If you’ve ever built a card that looks great in a wide sidebar and terrible in a narrow one, that’s the exact problem container queries solve. They’ve been stable across all major browsers since 2023, so in 2026 there’s no real reason to keep reaching for media query hacks.

Why media queries weren’t enough

Media queries ask one question: how wide is the viewport? That works fine for page-level layout. It falls apart for reusable components. A card in a three-column grid and the same card in a single-column feed see the same viewport width, so both get the same media query treatment even though they’re rendered at completely different sizes.

Before container queries, people worked around this with JavaScript resize observers, duplicated component variants, or just accepted that the component would look wrong somewhere. Container queries move that logic into CSS where it belongs.

The two things you need to know

There are two pieces: you declare a containment context on a parent, then you write rules inside a @container block that respond to that parent’s size.

/* 1. Mark the parent as a query container */
.card-wrapper {
 container-type: inline-size;
 container-name: card;
}

/* 2. Style the child based on the container's width */
.card {
 display: grid;
 gap: 1rem;
}

@container card (min-width: 400px) {
 .card {
 grid-template-columns: 160px 1fr;
 align-items: center;
 }
}

When .card-wrapper is narrower than 400px, the card stacks. When it’s wider, the image and text sit side by side. The viewport never enters the equation.

container-type values

  • inline-size: queries the inline (usually horizontal) dimension. This is what you want 95% of the time.
  • size: queries both dimensions. Only works if the container’s size doesn’t depend on its contents, so use it sparingly.
  • normal: the default, no size containment. You can still use style queries with it.

One gotcha: container-type: inline-size applies layout, style, and size containment on the inline axis. That means the container’s width can no longer be driven by its children. If you have a shrink-to-fit element, adding a container type can change its behavior. Set an explicit width or let the parent grid handle it.

Naming containers (and why you should)

If you don’t name a container, @container resolves against the nearest ancestor with a containment context. In a deeply nested layout that can be a surprise. Naming makes the target explicit:

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

@container sidebar (min-width: 300px) {
 .widget-title { font-size: 1.25rem; }
}

@container main (min-width: 700px) {
 .widget-title { font-size: 2rem; }
}

The container shorthand sets name and type in one line. Same component, two different containers, two different results. That’s the whole point.

Container query units

Alongside the at-rule you get container-relative units, which are genuinely useful for fluid type inside a component:

  • cqw: 1% of the container’s width
  • cqh: 1% of the container’s height
  • cqi: 1% of the container’s inline size
  • cqb: 1% of the container’s block size
  • cqmin / cqmax: the smaller or larger of the two
.card-title {
 /* scales with the card, not the screen */
 font-size: clamp(1rem, 4cqi, 1.75rem);
}

That clamp means the heading stays readable whether the card is 200px or 800px wide, without a single breakpoint.

Style queries

Style queries let you respond to a custom property value on an ancestor. Support is narrower than size queries (Safari is the holdout as of early 2026), so treat them as progressive enhancement.

.theme-dark { --theme: dark; }

@container style(--theme: dark) {
 .badge {
 background: #1a1a1a;
 color: #f5f5f5;
 }
}

This is handy for theming components without threading a class through every element, but check your browser targets before leaning on it in production.

When to use container queries vs. media queries

Use container queries for anything reusable: cards, buttons with icons, nav items, form fields, table cells. Use media queries for page-level decisions: overall grid columns, whether the sidebar exists at all, print styles, and user preferences like prefers-reduced-motion.

They’re not competitors. A typical 2026 layout uses media queries to decide the page skeleton and container queries to make the pieces inside that skeleton behave. If you’re rebuilding a site and want the components to hold up across every placement, this is the pattern I reach for on most Long Island web design projects now, and it cuts a lot of the back-and-forth out of responsive QA.

Browser support and fallbacks

Container size queries are supported in Chrome, Edge, Firefox, and Safari, going back several versions. If you still need to support something ancient, the fallback is straightforward: write sensible default styles outside the @container block, then let the query enhance them. Browsers that don’t understand @container ignore the whole block, so the component still renders, just in its stacked form.

/* Default: stacked. Works everywhere. */
.card { display: grid; gap: 1rem; }

/* Enhancement: only applies where container queries work. */
@container card (min-width: 400px) {
 .card { grid-template-columns: 160px 1fr; }
}

That’s the correct order anyway. Mobile-first, then layer on the wider layout.

Common mistakes

  • Forgetting container-type on the parent and wondering why nothing fires.
  • Using container-type: size on a container whose height comes from its content. It will collapse or behave oddly.
  • Querying the viewport with @container when you meant @media. They look similar but resolve against different boxes.
  • Nesting unnamed containers and losing track of which one wins. Name them.

FAQ

Do container queries replace media queries?

No. Media queries still handle viewport-level layout and user preferences. Container queries handle component-level responsiveness. Most real projects use both.

Can I use container queries in production in 2026?

Yes. Size queries are supported in all current major browsers. Style queries are still rolling out, so use them with a fallback.

What’s the difference between inline-size and size?

inline-size queries only the horizontal axis and is safe for content-sized elements. size queries both axes but requires the container to have a size independent of its contents.

Have a project like this?

I do Long Island web design for Long Island businesses. If you need this done right, let’s talk.