Skip to main content

CSS Container Queries Guide

Build truly responsive components that adapt to their container, not just the viewport.
Complete guide with interactive examples and copy-ready code.

What are Container Queries?

Container queries let you style elements based on the size of their containing element, rather than the viewport. This is a game-changer for building truly reusable, responsive components.

Before container queries, a card component would look the same whether it was in a narrow sidebar or a wide main content area. With container queries, the same component can adapt its layout based on the available space in its container.

The problem they solve: Media queries only know about the viewport. Container queries know about the actual space available to your component.

Browser Support

Container Queries are supported in all modern browsers since 2023.

Chrome
105+
Firefox
110+
Safari
16+
Edge
105+
Opera
91+

Global usage: ~93% of users have container query support (as of 2024).

Container Queries vs Media Queries

FeatureMedia QueriesContainer Queries
Based onViewport sizeContainer size
Use casePage-level layoutsComponent-level responsiveness
ReusabilityLimited - tied to viewportHigh - adapts to any container
Syntax@media@container
Unitsvw, vhcqw, cqh, cqi, cqb

Setting Up a Container

container-type: inline-size

The most common type. Enables container queries based on the container's width (inline dimension). The container can still have intrinsic height.

.card-container {
  /* Enable size queries on inline axis (width) */
  container-type: inline-size;
}

container-type: size

Enables container queries based on both width and height. Requires the container to have explicit dimensions. Use sparingly as it creates more layout constraints.

.card-container {
  /* Enable size queries on both axes */
  container-type: size;
  /* Note: requires explicit height */
  height: 400px;
}

Warning: Using size can break layouts if the container doesn't have explicit height. Most cases only need inline-size.

container-name

Name your containers to target them specifically in container queries. Useful when you have nested containers or multiple containers on the same page.

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

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

container (shorthand)

Combine name and type in a single declaration using the shorthand property.

.card-container {
  /* Shorthand: container: name / type */
  container: card / inline-size;
}

/* Equivalent to: */
.card-container {
  container-name: card;
  container-type: inline-size;
}

Writing Container Queries

Basic Syntax

Use @container to apply styles when the container reaches a certain size. Works like media queries but responds to the parent container, not the viewport.

/* Basic container query */
@container (min-width: 400px) {
  .card {
    display: flex;
    gap: 1rem;
  }
}

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

Named Container Queries

Target specific containers by name. Essential when working with nested containers or multiple query contexts.

/* Target a specific named container */
@container sidebar (min-width: 200px) {
  .nav-item {
    padding: 0.75rem 1rem;
  }
}

@container main (min-width: 600px) {
  .article {
    columns: 2;
  }
}

Range Queries

Use modern range syntax for cleaner conditions. Combine multiple conditions with and.

/* Range syntax (modern) */
@container (400px <= width <= 800px) {
  .card {
    padding: 1.5rem;
  }
}

/* Multiple conditions */
@container (min-width: 300px) and (max-width: 500px) {
  .card {
    font-size: 0.875rem;
  }
}

Height Queries

Query based on container height. Requires container-type: size on the container.

/* Height-based queries (requires container-type: size) */
@container (min-height: 300px) {
  .panel {
    padding: 2rem;
  }
}

/* Combining width and height */
@container (min-width: 400px) and (min-height: 300px) {
  .panel {
    display: grid;
    grid-template-columns: 1fr 1fr;
  }
}

Container Query Units

Container Query Units Reference

Container query units are relative to the size of the query container, similar to how viewport units (vw, vh) are relative to the viewport.

UnitNameDescription
cqwContainer Query Width1% of the container's width
cqhContainer Query Height1% of the container's height
cqiContainer Query Inline1% of the container's inline size (width in horizontal writing)
cqbContainer Query Block1% of the container's block size (height in horizontal writing)
cqminContainer Query MinSmaller value of cqi or cqb
cqmaxContainer Query MaxLarger value of cqi or cqb

Using Container Units

Use container units for truly fluid typography and spacing that responds to the component's container, not the viewport.

.card {
  /* Font size scales with container width */
  font-size: clamp(1rem, 4cqi, 2rem);

  /* Padding relative to container */
  padding: 5cqi;
}

.hero-text {
  /* Responsive typography based on container */
  font-size: 8cqw;
  line-height: 1.2;
}

.square-element {
  /* Use cqmin for elements that should stay square */
  width: 50cqmin;
  height: 50cqmin;
}

Practical Examples

Interactive Card Demo

Drag the slider to resize the container and see how the card layout adapts.

Responsive Card

This card changes layout based on its container width, not the viewport.

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

.card {
  padding: 1rem;
  background: white;
  border-radius: 0.5rem;
}

@container card (min-width: 400px) {
  .card {
    display: flex;
    gap: 1.5rem;
  }

  .card-image {
    width: 150px;
    flex-shrink: 0;
  }
}

Sidebar Navigation Demo

Resize to see icons-only vs icons with labels based on sidebar width.

Dashboard
Profile
Settings
.sidebar {
  container: sidebar / inline-size;
}

.nav-item {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.5rem;
  border-radius: 0.5rem;
}

.nav-label {
  display: none;
}

@container sidebar (min-width: 200px) {
  .nav-label {
    display: block;
  }
}

Article Layout Demo

Watch how the article switches from single column to multi-column based on container size. The title also uses container units for fluid typography.

Container Queries

Container queries revolutionize responsive design by allowing components to adapt based on their container size, not just the viewport.

This means a card component can look different in a sidebar versus a main content area, automatically.

Combined with container query units like cqw and cqi, you can create truly fluid, container-aware designs.

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

.article {
  padding: 1.5rem;
}

.article-title {
  font-size: 5cqi;
  margin-bottom: 1rem;
}

@container article (min-width: 600px) {
  .article {
    padding: 2.5rem;
  }

  .article-body {
    columns: 2;
    column-gap: 2rem;
  }
}

@container article (min-width: 800px) {
  .article-body {
    columns: 3;
  }
}

When to Use Container vs Media Queries

When to Use Each

@mMedia Queries

  • - Page-level layout changes
  • - Global navigation responsive behavior
  • - Overall grid column changes
  • - When the component ALWAYS takes full viewport width

@cContainer Queries

  • - Reusable component responsiveness
  • - Cards, widgets, or panels in varying contexts
  • - Sidebar content that collapses/expands
  • - Any component used in multiple layout contexts

Pro tip: Use container queries for components and media queries for layout. They work great together - use media queries to change how many columns your grid has, then let container queries handle how each component looks within those columns.

Key Takeaways

1. Set up the container with container-type: inline-size on the parent element.

2. Write container queries using @container to style children based on container size.

3. Use container units like cqw and cqi for fluid sizing relative to the container.

4. Name your containers with container-name when you have nested or multiple containers.