1. css
  2. /container queries

CSS Container Queries

What are CSS Container Queries?

CSS Container Queries allow you to style elements based on the size of their containing element rather than the viewport size. This enables truly modular, responsive components that can adapt to their context regardless of where they're placed on the page.

Unlike media queries that respond to viewport dimensions, container queries respond to the dimensions of a specific container element, making components more modular and reusable.

Browser Support

Container queries are well-supported in modern browsers:

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

Basic Syntax

To use container queries, you need to:

  1. Establish a containment context
  2. Write container queries that respond to that context

Step 1: Define Container Context

.container {
  container-type: inline-size;
  /* or use the shorthand */
  container: inline-size;
}

Step 2: Write Container Queries

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

Container Types

The container-type property accepts several values:

inline-size

Creates containment in the inline direction (width in horizontal writing modes):

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

@container (min-width: 300px) {
  .widget {
    padding: 2rem;
  }
}

size

Creates containment in both dimensions:

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

@container (min-width: 400px) and (min-height: 300px) {
  .card {
    aspect-ratio: 16/9;
  }
}

block-size

Creates containment in the block direction:

.content-area {
  container-type: block-size;
}

@container (min-height: 500px) {
  .article {
    columns: 2;
  }
}

Named Containers

You can name containers for more specific targeting:

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

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

/* Target specific container */
@container main (min-width: 800px) {
  .article {
    columns: 3;
  }
}

@container sidebar (min-width: 250px) {
  .widget {
    flex-direction: row;
  }
}

Container Query Units

Container queries introduce new length units:

  • cqw - 1% of container's width
  • cqh - 1% of container's height
  • cqi - 1% of container's inline size
  • cqb - 1% of container's block size
  • cqmin - Smaller value between cqi or cqb
  • cqmax - Larger value between cqi or cqb
.container {
  container-type: size;
}

.responsive-text {
  font-size: clamp(1rem, 4cqi, 2rem);
  padding: 2cqi;
}

.square {
  width: 50cqmin;
  height: 50cqmin;
}

Practical Examples

Responsive Card Component

.card-container {
  container-type: inline-size;
  padding: 1rem;
}

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

/* Small container - stack content */
.card {
  display: block;
}

.card img {
  width: 100%;
  margin-bottom: 1rem;
}

/* Medium container - side by side */
@container (min-width: 400px) {
  .card {
    display: flex;
    gap: 1rem;
  }
  
  .card img {
    width: 150px;
    margin-bottom: 0;
  }
}

/* Large container - more spacing */
@container (min-width: 600px) {
  .card {
    padding: 2rem;
    gap: 2rem;
  }
  
  .card img {
    width: 200px;
  }
}
.nav-container {
  container-type: inline-size;
}

.nav {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

/* Default - stacked menu */
.nav-menu {
  flex-direction: column;
  width: 100%;
}

/* Wide container - horizontal menu */
@container (min-width: 600px) {
  .nav-menu {
    flex-direction: row;
    width: auto;
  }
}

Best Practices

1. Start with Container Context

Always establish the containment context before writing container queries:

/* ✓ Good */
.component-wrapper {
  container-type: inline-size;
}

@container (min-width: 400px) {
  .component { /* styles */ }
}

/* ✗ Bad - no containment context */
@container (min-width: 400px) {
  .component { /* styles */ }
}

2. Use Meaningful Container Names

/* ✓ Good */
.product-grid {
  container: products / inline-size;
}

@container products (min-width: 600px) {
  .product-card {
    width: calc(50% - 1rem);
  }
}

/* ✗ Less clear */
.wrapper {
  container: c1 / inline-size;
}

3. Consider Performance

Container queries can be expensive. Use them judiciously:

/* ✓ Good - specific targeting */
.card-container {
  container-type: inline-size;
}

/* ✗ Avoid - too broad */
* {
  container-type: inline-size;
}

4. Progressive Enhancement

Provide fallbacks for older browsers:

/* Base styles for all browsers */
.card {
  display: block;
  padding: 1rem;
}

/* Enhanced layout with container queries */
@supports (container-type: inline-size) {
  .card-container {
    container-type: inline-size;
  }

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

Debugging Tips

  1. Use browser dev tools to inspect container contexts
  2. Add visual indicators for containers during development:
[style*="container"] {
  outline: 2px dashed blue;
}

[style*="container"]::before {
  content: "Container";
  background: blue;
  color: white;
  padding: 2px 4px;
}

Common Use Cases

  1. Component-based layouts: Cards, widgets, sidebars
  2. Responsive typography: Text that adapts to container size
  3. Flexible grids: Grid layouts that respond to container width
  4. Navigation patterns: Menus that adapt to available space
  5. Media containers: Images and videos that fit their container

Container queries represent a major evolution in responsive design, enabling truly modular and reusable components that can adapt to any context.