EmpireUI
Get Pro
← Blog7 min read#css-container-queries#responsive-design#css

CSS Container Queries in 2027: Fully Baseline, New Use Cases

CSS container queries hit Baseline in 2024 — but 2027 is when they get truly interesting. Here's what changed, what's new, and how to use them today.

Code editor showing CSS container query rules with colored syntax highlighting on a dark background

Container Queries Are Finally Just CSS

Honestly, container queries took about three years longer to feel "normal" than they should have. They shipped in Chrome 105 back in 2022, Firefox and Safari followed, and by late 2024 they were officially Baseline. But Baseline just means the spec is locked — it doesn't mean developers started using them confidently.

Here in 2026 the story has changed. You don't need a polyfill. You don't need to check caniuse before every commit. Container queries work everywhere your users are, and the mental model has finally clicked for most teams.

This article is about what comes after the basics. If you've written @container before, we'll skip the introductory stuff and talk about the new use cases — style queries, container query units, and how this changes the way you build component libraries like Empire UI.

A Quick Recap: Size Queries You Already Know

The original container query spec was about size. You name a container, set container-type, and then write breakpoints relative to that container's width or height. The classic card-inside-a-sidebar example. A component that reflows based on the space it's placed in, not the viewport.

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

@container card (min-width: 400px) {
  .card {
    display: grid;
    grid-template-columns: 120px 1fr;
    gap: 16px;
  }
}

@container card (max-width: 399px) {
  .card {
    display: flex;
    flex-direction: column;
    gap: 8px;
  }
}

That pattern still holds. What's changed is the ecosystem around it — new query types, new units, and better tooling support in both vanilla CSS and in frameworks like Tailwind v4.

Style Queries: The Part Everyone Slept On

Size queries are useful. Style queries are where things get weird in a good way. With style queries, you can query the computed value of a CSS custom property on the container element. That means you can let a parent signal context to children without JavaScript.

The practical use case: you have a Card component used in both a light sidebar and a dark promotional banner. Instead of passing a variant prop and forking your styles, the container tells the card what context it's in.

.promo-banner {
  container-name: theme-context;
  --surface: dark;
}

@container theme-context style(--surface: dark) {
  .card {
    background: rgba(255, 255, 255, 0.08);
    color: #f0f0f0;
    border: 1px solid rgba(255, 255, 255, 0.15);
  }
}

@container theme-context style(--surface: light) {
  .card {
    background: #ffffff;
    color: #1a1a1a;
    border: 1px solid #e2e2e2;
  }
}

This pairs naturally with glassmorphism patterns, where you're already layering rgba backgrounds and borders to signal depth. Style queries let the blur and transparency respond to context without adding prop drilling.

Container Query Units: cqi, cqb, cqw, cqh

These landed alongside the main spec but people barely talk about them. cqi is 1% of the container's inline size. cqb is 1% of the block size. cqw and cqh map to width and height regardless of writing mode. Think of them as vw and vh but scoped to the container.

Why does that matter? Typography. You can now scale font sizes relative to the container, not the viewport. A heading inside a full-width hero can be 4cqi and feel huge. That same heading dropped into a 280px sidebar card becomes reasonable automatically. No media query. No clamp() workarounds.

// React component using CQ units via inline styles + CSS
.feature-card h2 {
  font-size: clamp(1rem, 4cqi, 2.5rem);
  line-height: 1.2;
}

.feature-card p {
  font-size: clamp(0.875rem, 2.5cqi, 1.125rem);
  margin-top: 0.5em;
}

This is the kind of thing that makes you rethink how you build reusable components. Instead of hardcoding font sizes in variants, you define a single responsive rule and the component scales itself. It's less code to maintain.

Tailwind v4 and Container Queries

Tailwind v4 shipped first-class container query support without a plugin. You can write @container in component classes directly, and the new @max-* and @min-* variants just work. Tailwind v4.0.2 specifically cleaned up some edge cases around named containers that were annoying in the alpha.

The syntax looks like this in a TSX file using Tailwind's arbitrary value approach:

// Named container in your layout
<div className="[container-type:inline-size] [container-name:sidebar]">
  <div className="@[300px]:flex-row @[500px]:grid @[500px]:grid-cols-2 flex flex-col gap-4">
    {children}
  </div>
</div>

The @[300px]: prefix is Tailwind's container query variant syntax. It's not quite as clean as writing raw CSS, but it means you can use container-responsive classes without touching a stylesheet. For teams that are already deep in a Tailwind workflow with libraries like Empire UI, this fits right in. It also pairs nicely with the theme toggle pattern since container queries don't conflict with dark mode class toggling.

One thing to watch: container-type: size queries on both axes are expensive. Use inline-size unless you genuinely need height-based queries. The browser has to do layout passes to compute size, and blocking both axes can slow things down on complex pages.

Real-World Patterns: Dashboards and Design Systems

Where do container queries actually shine in production? Dashboards. A metrics widget that lives in a full-width row should show a sparkline, a number, and a label. That same widget dropped into a 200px side panel should show just the number. You can't know at build time where it'll land.

Without container queries, you'd solve this with props — size="compact" vs size="full". That leaks layout logic into your JavaScript. Your component now has to know its context. With container queries, the CSS handles it and your React component stays dumb about its environment.

The same logic applies to design systems. If you're building a component library meant to drop into any layout, container queries let you write self-contained components that adapt without configuration. That's a meaningful reduction in the number of prop variants you need to document and maintain. Check out how CSS Houdini paint worklets can layer on top of this for custom background rendering inside those adaptive containers.

What Still Doesn't Work (and When It Will)

Let's be honest about the gaps. Scroll-state container queries — querying whether a container is stuck (like a sticky header) — are still behind a flag in Chrome as of late 2026. It's coming, but it's not Baseline yet. Don't ship it in production without a fallback.

Height-based container queries remain rare because querying block-size requires the container to have a defined height, which most containers don't. You'd need an explicit height or max-height set. This trips people up. They expect it to work like min-height: 0 on flex children and it doesn't.

What about querying a container's own styles other than custom properties? That's not in the spec. You can't do @container style(background-color: red) — only custom properties work for style queries. That's a deliberate choice to avoid cyclical dependency issues, but it does limit some patterns you might imagine.

Combining Container Queries With Modern Layout Techniques

Container queries work best when they're one tool in a larger layout strategy, not a silver bullet. grid and subgrid handle the macro layout. Container queries handle component-level adaptation. CSS custom properties handle theming. They layer well together.

One pattern worth stealing: use CSS Grid for your page shell, name each grid area as a container, and let all components inside adapt to their grid area's size. The header area might be 1200px wide; the sidebar might be 240px. Components dropped into either just work.

.app-shell {
  display: grid;
  grid-template-columns: 240px 1fr;
  grid-template-rows: 60px 1fr;
  grid-template-areas:
    'nav    header'
    'nav    main';
}

.nav-area   { grid-area: nav;    container: nav-panel / inline-size; }
.main-area  { grid-area: main;   container: main-content / inline-size; }

This works particularly well when you're building animated layouts — the container size changes on resize and CSS transitions can animate the properties that change. Components using parallax effects inside a main-content container, for example, can now adapt their parallax intensity to the available space.

FAQ

Do I need a polyfill for CSS container queries in 2026?

No. Container queries are fully Baseline and supported across Chrome, Firefox, and Safari without any polyfill. The old container-query-polyfill package from Google Chrome Labs is no longer needed for new projects.

What's the difference between container-type: inline-size and container-type: size?

Using inline-size lets you query the container's width (in horizontal writing modes). Using size lets you query both width and height, but it's more expensive because the browser can't use its single-axis layout optimization. Use inline-size unless you specifically need height queries.

Can I use CSS container query units (cqi, cqw) in Tailwind v4?

Yes, via arbitrary values. You'd write something like text-[4cqi] for font sizes, or use them in arbitrary CSS inside @layer blocks. Tailwind v4.0.2 doesn't strip CQ units as unknown values the way older versions did.

Style queries only work with custom properties — why can't I query regular CSS properties?

The spec intentionally limits style queries to custom properties to avoid circular dependencies. If you could query background-color, a rule might change the background which triggers itself again. Custom properties don't participate in the cascade the same way, so they're safe to query.

How do container queries interact with React and component-based architecture?

They complement each other well. The container setup (container-type, container-name) usually lives in a layout or wrapper component's CSS. The adaptive styles live in the inner component's CSS. The React component itself doesn't need to know anything about its context — the CSS handles it.

Are scroll-state container queries (like querying if a sticky element is stuck) production-ready?

Not yet as of late 2026. Scroll-state queries are behind a flag in Chrome and haven't shipped in Firefox or Safari. They're worth watching but you'll need a JavaScript IntersectionObserver workaround for production sticky-state detection for now.

Free components in 40 styles
React & Tailwind, copy-paste ready.
Browse →

Read next

CSS Subgrid in Production: Aligning Children Across Rows and ColsNative CSS Nesting: Full Guide with Real Component ExamplesTailwind CSS Mastery: Every Utility, Plugin, and Pattern in One GuideTailwind Container Queries: Responsive Components Without Media Queries