ESC
Type to search guides, tutorials, and reference documentation.
Verified by Garnet Grid

CSS Container Queries

Build truly responsive components that adapt to their container size, not just the viewport. Covers container query syntax, use cases vs media queries, component-driven responsive design, and the patterns that make components reusable across any layout context.

Media queries respond to the browser viewport. Container queries respond to the size of the component’s parent container. This is the difference between “is the screen small?” and “is this component’s space small?” Container queries let you build components that adapt to where they are placed — in a sidebar, a full-width section, or a card grid — without knowing anything about the page layout.


Container Queries vs. Media Queries

/* Media Query: Responds to viewport size */
/* Problem: Component doesn't know if it's in a sidebar or main content */
@media (max-width: 768px) {
  .card { flex-direction: column; }
}

/* Container Query: Responds to container size */
/* Component adapts to its OWN available space */
.card-container {
  container-type: inline-size;
  container-name: card-wrapper;
}

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

@container card-wrapper (max-width: 399px) {
  .card {
    display: flex;
    flex-direction: column;
  }
  
  .card-image {
    width: 100%;
    aspect-ratio: 16/9;
  }
}

Real-World Use Cases

/* Responsive card component that works anywhere */
.widget-area {
  container-type: inline-size;
}

/* Stats widget: horizontal when wide, stacked when narrow */
@container (min-width: 500px) {
  .stats-widget {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
  
  .stat-item {
    text-align: center;
    flex: 1;
    border-right: 1px solid var(--color-border);
  }
  
  .stat-item:last-child {
    border-right: none;
  }
}

@container (max-width: 499px) {
  .stats-widget {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.5rem;
  }
  
  .stat-item {
    padding: 0.75rem;
    background: var(--color-bg-secondary);
    border-radius: var(--radius-md);
  }
}

/* Navigation: horizontal tabs when wide, hamburger when narrow */
@container (min-width: 600px) {
  .nav-tabs {
    display: flex;
    gap: 0;
  }
  
  .nav-hamburger { display: none; }
}

@container (max-width: 599px) {
  .nav-tabs {
    display: none;
  }
  
  .nav-tabs.open {
    display: flex;
    flex-direction: column;
    position: absolute;
    width: 100%;
  }
  
  .nav-hamburger { display: block; }
}

Anti-Patterns

Anti-PatternConsequenceFix
Container queries for everythingUnnecessary complexity for simple layoutsUse media queries for page layout, container queries for components
No fallback for older browsersComponent breaks in Safari < 16Feature query: @supports (container-type: inline-size)
container-type: sizeRequires explicit height, causes layout issuesUse container-type: inline-size for most cases
Deeply nested containersPerformance impact, confusing cascadeLimit nesting to 2-3 levels
Not setting container-nameAmbiguous which container is queriedAlways name containers explicitly

Container queries complete the responsive design toolkit. Media queries handle page-level layout; container queries handle component-level adaptation. Together, they let you build components that are truly reusable — dropping into any layout context and adapting intelligently.

Jakub Dimitri Rezayev
Jakub Dimitri Rezayev
Founder & Chief Architect • Garnet Grid Consulting

Jakub holds an M.S. in Customer Intelligence & Analytics and a B.S. in Finance & Computer Science from Pace University. With deep expertise spanning D365 F&O, Azure, Power BI, and AI/ML systems, he architects enterprise solutions that bridge legacy systems and modern technology — and has led multi-million dollar ERP implementations for Fortune 500 supply chains.

View Full Profile →