CSS Container Queries: Complete Guide for Modern Web Developers 2026
Guide · Updated 2026

CSS Container Queries:
The Complete Guide for Modern Web Developers

Everything you need to know about CSS Container Queries in 2026 — from basic setup to advanced patterns. Practical examples, real-world use cases, and browser support from a senior frontend developer with 20+ years of experience.

Oleg Maximov May 18, 2026 18 min read

Introduction

If you've ever built a reusable component and struggled to make it look right in every possible parent context — a narrow sidebar, a wide main area, a full-width hero section — CSS Container Queries are the solution you've been waiting for.

Before container queries, the only way to make components responsive was to use media queries, which respond to the viewport size. But a component doesn't care about the viewport — it cares about the space its container gives it. A card component displayed in a 300px sidebar and a 900px content area should adapt to its own available space, not the browser window.

Container queries solve this. They let you query the size of a parent container and apply styles accordingly. This makes components truly self-contained, reusable, and context-aware — a paradigm shift in how we build responsive interfaces.

In this guide, I'll take you from zero to production-ready with container queries. You'll learn the syntax, the units, the pitfalls, and the patterns that work in real applications. I've used container queries on production projects since they landed in Chrome 105 — these are battle-tested techniques, not theoretical examples.

What Are CSS Container Queries?

A CSS Container Query is a @container rule that applies styles based on the dimensions of a named container rather than the viewport. To create a container, you use the container-type property (or the shorthand container) on a parent element.

The core idea is simple:

  1. Define a container by setting container-type on a parent element
  2. Write a container query with @container (min-width: 400px) for child elements
  3. The child adapts automatically when the parent crosses the size threshold

This is fundamentally different from media queries, which only know about the viewport. A card in a 300px-wide container inside a 1920px viewport triggers container query styles at 300px, not 1920px. The component is truly reusable.

Container Query Syntax: The Fundamentals

Defining a Container

The container-type property defines an element as a query container. The most common value is inline-size, which creates a container that tracks the inline (width) dimension:

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

You can also name your container using container-name. This is useful when you have nested containers and need to target a specific one:

.sidebar {
  container-type: inline-size;
  container-name: sidebar;
}

.main-content {
  container-type: inline-size;
  container-name: content;
}

The shorthand container combines both properties:

/* container: <name> / <type> */
.card-grid {
  container: card-grid / inline-size;
}

Writing Container Queries

Once a container is defined, any descendant can query it with the @container rule:

.card {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
}

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

@container (min-width: 600px) {
  .card {
    grid-template-columns: 1fr 1fr 1fr;
  }
}

When the container is named, reference it in the query:

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

💡 Best Practice: Always name your containers when you have nesting. Unnamed queries match the nearest ancestor container with container-type, which can produce surprising results in complex layouts. Naming makes the intent explicit.

Container Query Units: cqw, cqh, cqi, cqb, cqmin, cqmax

Alongside container queries came container query units — relative length units that work just like viewport units (vw, vh) but refer to the container's dimensions instead of the viewport.

Unit Relative To Equivalent to Viewport Unit Use Case
cqw 1% of container width vw Horizontal sizing, padding
cqh 1% of container height vh Vertical sizing, sticky elements
cqi 1% of container inline size vi Preferred for text and spacing in horizontal writing modes
cqb 1% of container block size vb Stack spacing, vertical rhythm
cqmin Smaller of cqi and cqb vmin Responsive icons, square elements
cqmax Larger of cqi and cqb vmax Full-coverage overlays within a container

Practical example — fluid typography that scales with the container:

.card-title {
  font-size: clamp(1rem, 4cqi, 2.5rem);
  padding: 1cqi 2cqi;
}

.card-image {
  width: 100%;
  height: 30cqh;
  object-fit: cover;
}

With cqi, typography scales proportionally to the container's inline size. The same component gets smaller text in a narrow sidebar and larger text in a wide content area — automatically, without a single media query.

💡 Pro tip: Use cqi instead of cqw for responsive typography. cqi respects the writing mode (it's the inline axis), so your design works in both horizontal and vertical writing modes without changes.

Media Queries vs Container Queries: When to Use Which

Container queries don't replace media queries — they complement them. Understanding when to reach for each is the key to a clean responsive architecture.

Scenario Use Why
Page-level layout (grid columns, sidebar visibility) @media The page structure should respond to viewport size
Reusable component styling (cards, widgets, forms) @container Components need to work in any container, regardless of viewport
Font size and spacing for readability cqi units Fluid scaling without query overhead; works everywhere
Print styles, reduced motion, dark mode @media These are user/browser-level preferences, not layout-dependent
Dashboard widget grid that reflows Both Media query for the page layout, container queries for individual widgets

A typical modern responsive project uses media queries for the macro layout (the page grid, header, footer) and container queries for the micro layout (individual components within that grid). This separation keeps your codebase clean and your components genuinely reusable.

Practical Example: A Fully Responsive Card Component

Let's build a real component — a product card that adapts to three different container widths without any media queries:

/* Define the container */
.product-grid-cell {
  container: product-card / inline-size;
}

/* Base card styles — works in narrowest context */
.product-card {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding: 1rem;
  border-radius: 0.75rem;
  background: var(--surface);
}

.product-card__image {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 0.5rem;
}

.product-card__title {
  font-size: clamp(0.9rem, 3cqi, 1.4rem);
  font-weight: 600;
}

.product-card__price {
  font-size: clamp(1rem, 2.5cqi, 1.5rem);
  font-weight: 700;
  color: var(--color-accent);
}

.product-card__description {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.product-card__button {
  display: none; /* Hidden in narrow layout */
}

/* Medium container: side-by-side layout */
@container product-card (min-width: 350px) {
  .product-card {
    flex-direction: row;
    align-items: center;
  }
  .product-card__image {
    width: 120px;
    height: 120px;
    flex-shrink: 0;
  }
}

/* Wide container: show the CTA button */
@container product-card (min-width: 500px) {
  .product-card__button {
    display: inline-flex;
  }
}

This card component works flawlessly in a 250px sidebar (vertical stack, no button), a 400px content column (horizontal layout), and a 600px+ main area (with CTA button). You place it in any grid cell, and it adapts automatically.

Real-World Patterns and Use Cases

1. Dashboard Widget Grids

Dashboard widgets are the ideal use case for container queries. A widget might need to display data differently depending on whether it's in a 1-column, 2-column, or 3-column grid layout. With container queries, each widget manages its own responsiveness without knowing about the grid:

.dashboard-widget {
  container: widget / inline-size;
  padding: 1rem;
  background: var(--surface);
  border-radius: 0.75rem;
}

/* Narrow: stacked chart, minimal labels */
@container widget (max-width: 300px) {
  .widget-chart { height: 150px; }
  .widget-legend { display: none; }
}

/* Medium: show legend, full chart */
@container widget (min-width: 301px and max-width: 500px) {
  .widget-chart { height: 250px; }
  .widget-legend { font-size: 0.8rem; }
}

/* Wide: detailed view with extra metrics */
@container widget (min-width: 501px) {
  .widget-chart { height: 350px; }
  .widget-footer { display: flex; }
}

2. Form Layouts That Adapt to Container

Forms need to work in modals, sidebars, and full pages. Container queries make this trivial:

.form-container {
  container: form-wrapper / inline-size;
}

@container form-wrapper (min-width: 500px) {
  .form-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1rem;
  }
}

@container form-wrapper (min-width: 700px) {
  .form-row {
    grid-template-columns: 1fr 1fr 1fr;
  }
}

3. Navigation Menus

Navigation components with container queries can switch from hamburger to horizontal menu based on the container width — not the viewport. This is especially useful for nested navigation bars and mega-menus:

.nav-container {
  container: nav / inline-size;
}

@container nav (max-width: 400px) {
  .nav-links-desktop { display: none; }
  .nav-hamburger { display: block; }
}

@container nav (min-width: 401px) {
  .nav-links-desktop { display: flex; }
  .nav-hamburger { display: none; }
}

Advanced Techniques

Combining Container Queries with CSS Grid

The most powerful pattern: use a CSS Grid with auto-fill and minmax for the page layout, then let container queries handle each cell's content. The grid automatically wraps items into new rows as the viewport shrinks, and the items adapt to their available width:

.product-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 1.5rem;
}

.product-grid > * {
  container: grid-item / inline-size;
}

With this pattern, the grid determines how many columns fit, and each grid item uses container queries to style its content. No media queries needed for the component — it responds to the container's width, which is determined by the grid.

Scope and Containment for Performance

Container queries automatically apply containment — specifically, contain: layout style inline-size when using inline-size. This means the browser can limit style recalculation to just the container subtree, which can improve rendering performance compared to global style changes.

However, be mindful of container nesting. If you nest containers inside containers, a size change at the outer level triggers recalculations for all inner containers. For most layouts this is fine — browsers optimize this well — but avoid nesting deeper than 3-4 levels in performance-critical areas.

Using container-type: size for Height-Aware Components

While inline-size is the recommended default, container-type: size tracks both width and height. Use this sparingly — it applies full containment (contain: layout style size), which can cause unexpected layout behavior because the element's intrinsic size becomes zero before query evaluation.

.aspect-aware-widget {
  container-type: size;
}

@container (min-height: 300px) {
  .widget-content {
    columns: 2;
  }
}

For most use cases, stick with inline-size. Height-based container queries are rarely necessary — content usually determines height naturally.

Browser Support and Baseline Status

As of May 2026, CSS Container Queries are supported in all major browsers:

Container queries reached Baseline" (widely available) status in early 2024. No polyfills are needed for any browser with reasonable market share. The only gap would be very old browsers (IE11 pre-Chromium Edge), which account for under 0.5% of global traffic in 2026.

The container query units (cqw, cqh, cqi, cqb, cqmin, cqmax) have identical support — they landed alongside the queries and are available in the same browser versions.

Common Pitfalls and How to Avoid Them

1. Unnamed Containers in Nested Layouts

Without a name, @container queries the nearest ancestor container. In deeply nested components, this can target the wrong container. Always name your containers to make the relationship explicit.

2. Using size Instead of inline-size

container-type: size applies full containment, which can break layouts because the element collapses to zero intrinsic dimensions. Unless you specifically need height queries, use inline-size.

3. Forgetting About Container Queries in Design Systems

If you're building a design system or component library, container queries are a natural fit. But if your consumers wrap your component in another container, the query might match the wrong size. Document your container naming conventions clearly.

4. Over-relying on Container Queries for Everything

Not every responsive problem needs a container query. If a component only ever appears in one context (e.g., a site header), a media query is simpler and more predictable. Container queries are valuable when a component appears in multiple contexts with different available widths.

CSS Container Queries vs Other Modern CSS Features

Container queries work beautifully alongside other modern CSS features. Here's how they complement each other:

.product-card {
  container: product-card / inline-size;

  & .title {
    font-size: clamp(1rem, 3cqi, 1.5rem);
  }

  @container product-card (min-width: 400px) {
    & {
      flex-direction: row;
    }
  }
}

For more on modern JavaScript features that work alongside these CSS capabilities, see my ES2026 Complete Guide.

FAQ

What are CSS Container Queries?
CSS Container Queries let you style elements based on the size of their parent container rather than the viewport (as media queries do). A container query watches a defined container element and applies styles when that container reaches certain dimensions, enabling truly reusable, context-aware components.
How do CSS Container Queries differ from media queries?
Media queries respond to the viewport size, making them a one-size-fits-all approach. Container queries respond to the size of a specific parent element. This means a component inside a narrow sidebar and the same component in a wide main content area can adapt independently, without needing separate responsive breakpoints for each context.
What container query units are available?
Container query units include: cqw (1% of container width), cqh (1% of container height), cqi (1% of container inline size), cqb (1% of container block size), cqmin (the smaller of cqi and cqb), and cqmax (the larger of cqi and cqb). These work like viewport units but relative to the container instead of the viewport.
Do CSS Container Queries work in all browsers?
Yes, CSS Container Queries are supported in all major browsers as of 2026: Chrome 105+, Firefox 110+, Safari 16+, and Edge 105+. They reached Baseline status (widely available) in 2024. No polyfills are needed for modern browsers.
What is the difference between container-type inline-size and size?
container-type: inline-size creates a container that only tracks the inline (width) dimension, which avoids layout instability from height changes. container-type: size tracks both width and height but triggers containment on both axes, which can cause unexpected layout shifts. For most use cases, inline-size is recommended.
Can container queries and media queries be used together?
Absolutely. Container queries handle component-level responsiveness while media queries handle page-level layout changes. The best responsive designs use both: media queries for the grid or page structure, and container queries for components within that grid. For a complete take on modern CSS and JS together, see my ES2026 Complete Guide.
Do container queries affect performance?
Container queries are well-optimized in modern browsers. The containment they enforce can actually improve performance by limiting style recalculation scope. The main performance consideration is that changes to a container's size trigger style recalculations for all children with container queries, so deep nesting of many container query elements should be used thoughtfully.

Getting Started: Your First Container Query

Ready to try container queries in your project? Here's the simplest possible setup:

/* 1. Define the container on any parent element */
.responsive-wrapper {
  container: wrapper / inline-size;
}

/* 2. Style children that adapt to container width */
.my-component {
  padding: 1rem;
}

@container wrapper (min-width: 450px) {
  .my-component {
    padding: 2rem;
    display: grid;
    grid-template-columns: 1fr 1fr;
  }
}

That's it. Add container to a parent, write @container for the children, and your component becomes container-aware. The browser handles the rest — no JavaScript, no ResizeObserver, no framework hacks.

If you're working on a responsive redesign or building a component library, container queries are one of the most impactful CSS features to adopt today. They will fundamentally change how you think about responsive design — for the better.

Need help implementing container queries in your project? I'm available for frontend architecture consulting and development. View my services or contact me directly.

Contact

Building a responsive web application?

I build production web applications using modern CSS and JavaScript. Let's discuss your project — free consultation.