CSS Container Queries Tutorial: Build Truly Responsive Components in 2026

For years, responsive design has been tied to one thing: the viewport. We’ve written thousands of @media (min-width: ...) rules to make our layouts adapt to the screen. But components don’t live in the viewport, they live inside containers. A card in a sidebar should look different from the same card in a hero section, even on the same screen size.

This is exactly what CSS container queries solve. In this tutorial, we’ll skip the theory-heavy intros you’ll find on MDN or CSS-Tricks and focus on what actually matters in 2026: building real components that respond to their parent’s size, with copy-paste code you can use today.

Why Container Queries Changed Front-End Development

Media queries answer the question: How big is the screen?
Container queries answer a much better question: How big is the space my component has to work with?

In a component-driven world (React, Vue, Svelte, Web Components), this is the missing piece. A single <Card /> component can now adapt itself depending on where it’s dropped, no props, no JavaScript, no ResizeObserver hacks.

Browser Support in 2026

Container queries are now fully supported across all evergreen browsers (Chrome, Edge, Firefox, Safari) and have been stable since 2023. You can safely use them in production without fallbacks for the vast majority of audiences.

responsive web design code

Step 1: Define a Container

Before you can query something, you need to tell CSS what is queryable. This is done with the container-type property.

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

/* Shorthand version */
.card-wrapper {
  container: card / inline-size;
}

Two values matter most:

  • inline-size: query the width (the most common, and the safest choice).
  • size: query both width and height (heavier, can cause layout issues).

Rule of thumb: use inline-size unless you have a very specific reason to need height-based queries.

Step 2: Query the Container

Now the magic part. Instead of @media, we use @container.

.card {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

@container card (min-width: 480px) {
  .card {
    flex-direction: row;
    align-items: center;
  }
}

That’s the entire mental model. The card switches from stacked to horizontal when its parent reaches 480px, not when the viewport does.

Real-World Pattern 1: The Adaptive Card

This is the killer use case. One card component, three different contexts: a wide hero, a 3-column grid, and a narrow sidebar.

<div class="card-wrapper">
  <article class="card">
    <img src="cover.jpg" alt="" class="card__img">
    <div class="card__body">
      <h3>Container Queries Rock</h3>
      <p>Truly responsive components.</p>
      <button>Read more</button>
    </div>
  </article>
</div>
.card-wrapper {
  container: card / inline-size;
}

.card {
  display: grid;
  gap: 1rem;
  padding: 1rem;
  border-radius: 12px;
  background: #fff;
}

.card__img {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

/* Medium container: side by side */
@container card (min-width: 420px) {
  .card {
    grid-template-columns: 200px 1fr;
    align-items: center;
  }
  .card__img { aspect-ratio: 1 / 1; }
}

/* Large container: hero-style */
@container card (min-width: 720px) {
  .card {
    grid-template-columns: 1fr 1fr;
    padding: 2rem;
  }
  .card__img { aspect-ratio: 4 / 3; }
  .card h3 { font-size: 2rem; }
}

Drop the same .card-wrapper into any layout and it will simply do the right thing. No props, no breakpoints in your JSX.

responsive web design code

Real-World Pattern 2: The Smart Sidebar

Sidebars are another perfect candidate. A user widget should show an avatar + name + role when there’s space, but collapse to just an avatar when squeezed.

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

.user {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.user__details { display: none; }

@container sidebar (min-width: 220px) {
  .user__details { display: block; }
}

@container sidebar (min-width: 320px) {
  .user__role { display: inline; }
}

Resize the sidebar and the widget reacts instantly. No JavaScript, no observers.

Container Queries vs Media Queries

Aspect Media Queries Container Queries
Reference Viewport / device Parent container
Best for Page-level layout Reusable components
Component reusability Low High
Syntax @media @container

Bonus: Container Query Units

Along with @container, you also get new length units that are relative to the container, not the viewport:

  • cqw: 1% of the container’s width
  • cqh: 1% of the container’s height
  • cqi: 1% of the container’s inline size
  • cqmin / cqmax: smaller / larger of cqi and cqb

This is fantastic for fluid typography inside components:

.card h3 {
  font-size: clamp(1rem, 4cqi, 2rem);
}
responsive web design code

Common Pitfalls to Avoid

  1. Don’t query the same element you turn into a container. Container queries style descendants, not the container itself.
  2. Avoid container-type: size unless needed. It forces both axes to be sized and can break layouts that rely on intrinsic height.
  3. Name your containers when you have nested ones, otherwise the query targets the nearest container, which may not be what you want.
  4. Don’t replace every media query. Page-level layout (grids, navigation drawers) is still best handled by media queries.

Style Queries: A Quick Look

In 2026, style queries (querying CSS custom properties on a container) are also available and great for theming variants:

.section { container-name: section; --theme: dark; }

@container section style(--theme: dark) {
  .card { background: #111; color: #fff; }
}

This unlocks variant-based styling without adding modifier classes everywhere.

FAQ

Are CSS container queries production-ready in 2026?

Yes. All major browsers have supported them for years. You can ship them with confidence.

Should I replace all my media queries with container queries?

No. Use media queries for page-level layout (sidebars appearing, navigation collapsing) and container queries for component-level adaptations. They complement each other.

Do container queries hurt performance?

Slightly, because the browser tracks container sizes. In practice the impact is negligible if you stick to inline-size and don’t wrap every single element as a container.

Can I use container queries with Tailwind CSS?

Yes. Tailwind ships an official container queries plugin with utility variants like @container, @sm:, @md: applied to descendants.

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

inline-size tracks only the container’s width (the inline axis in horizontal writing modes). size tracks both width and height but requires the container to have an intrinsic size, which can break flow layouts.

Wrapping Up

Container queries are not just another CSS feature, they’re a shift in how we think about responsive design. Instead of designing pages, we now design self-aware components. Combined with container query units and style queries, you can build a design system where every component just works, wherever it lands.

Start small: pick one card or one widget in your codebase, wrap it in a container, and watch it adapt. Once you see it in action, you’ll never go back to viewport-only thinking.

Leave a Comment