Programming

CSS Container Queries: Component-Level Responsive Design

Tech Setup2 min read
TS

Tech Setup

Published July 31, 2026 · Editorial policy

CSS Container Queries: Component-Level Responsive Design

The Problem with Media Queries

Media queries respond to the viewport width. But components live inside containers that may be narrow (sidebar) or wide (main content). A card component shouldn't care about the screen size — it should care about its own container.

Container Query Basics

1. Define a Container

.card-wrapper {
  container-type: inline-size;
  container-name: card;
}
  • inline-size: Track the width (not height)
  • container-name: Optional, useful when nesting containers

2. Query the Container

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

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

Practical Example: Card Component

HTML

<div class="card-wrapper">
  <article class="card">
    <img src="hero.jpg" alt="Hero" class="card-image" />
    <div class="card-body">
      <h3 class="card-title">Article Title</h3>
      <p class="card-excerpt">Short description of the article...</p>
      <div class="card-meta">
        <span class="card-date">Jan 15, 2026</span>
        <span class="card-tag">Tutorial</span>
      </div>
    </div>
  </article>
</div>

CSS

/* Container */
.card-wrapper {
  container-type: inline-size;
}

/* Base style (mobile-first) */
.card {
  border: 1px solid #333;
  border-radius: 8px;
  overflow: hidden;
}

.card-image {
  width: 100%;
  height: 200px;
  object-fit: cover;
}

.card-body {
  padding: 1rem;
}

.card-title {
  font-size: 1.25rem;
  margin: 0 0 0.5rem;
}

/* Wide container: side-by-side layout */
@container (min-width: 500px) {
  .card {
    display: grid;
    grid-template-columns: 250px 1fr;
  }

  .card-image {
    height: 100%;
  }

  .card-title {
    font-size: 1.5rem;
  }
}

/* Extra wide: add more metadata */
@container (min-width: 800px) {
  .card-meta {
    display: flex;
    gap: 1rem;
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid #333;
  }

  .card-title {
    font-size: 1.75rem;
  }
}

Container Query Units

UnitMeaning
cqw1% of container width
cqh1% of container height
cqi1% of container inline size
cqb1% of container block size
cqminSmaller of cqi and cqb
cqmaxLarger of cqi and cqb

Example: Fluid Typography

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

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

The font scales with the container, not the viewport.

Nesting Containers

You can nest containers. Each query only affects its direct parent:

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

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

/* Card in sidebar */
@container sidebar (max-width: 300px) {
  .card { /* compact layout */ }
}

/* Card in main content */
@container main (min-width: 600px) {
  .card { /* expanded layout */ }
}

Named vs Anonymous Containers

/* Anonymous — catches all @container rules */
.parent { container-type: inline-size; }

/* Named — only responds to matching queries */
.parent { container-type: inline-size; container-name: parent; }
@container parent (min-width: 500px) { ... }

Use named containers when you have multiple container types on the page.

Browser Support (2026)

BrowserSupport
Chrome 105+
Firefox 110+
Safari 16+
Edge 105+

Safe to use in production without fallbacks for modern browsers.

Container Queries vs Media Queries

FeatureMedia QueryContainer Query
Responds toViewportParent container
Use casePage layoutComponent layout
Responsive toScreen sizeAvailable space
NestingN/APer-container

Common Patterns

Grid Auto-Fit with Containers

.grid-wrapper {
  container-type: inline-size;
}

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 1rem;
}

/* Stack on narrow containers */
@container (max-width: 600px) {
  .grid {
    grid-template-columns: 1fr;
  }
}
.layout {
  container-type: inline-size;
}

@container (max-width: 768px) {
  .sidebar { display: none; }
  .main { width: 100%; }
}

@container (min-width: 769px) {
  .sidebar { width: 250px; }
  .main { flex: 1; }
}

Performance Notes

  • Container queries add minimal overhead
  • The browser already tracks layout for paint
  • Use contain: layout inline-size for best performance (set automatically by container-type)
  • Avoid querying very deeply nested containers