Scaling Nested Components with CSS Container Query Units

CSS container query units—specifically cqw, cqh, cqi, and cqb—allow developers to build deeply nested components that dynamically scale typography, padding, and layout based on their immediate container rather than the entire browser viewport. By decoupling component sizing from global media queries, nested elements adapt seamlessly whether they live inside a narrow sidebar, a grid item, or a full-width section.

The Core Container Units

Container query units represent a percentage of a designated container's dimensions:

  • cqw (Container Query Width): 1% of the query container's width.
  • cqh (Container Query Height): 1% of the query container's height.
  • cqi (Container Query Inline): 1% of the query container's inline size (width in horizontal writing modes).
  • cqb (Container Query Block): 1% of the query container's block size (height in horizontal writing modes).

Using cqi and cqb is generally preferred over cqw and cqh because they adapt to different international writing modes.

Establishing Containment

Before using these units, an ancestor element must declare a containment context using the container-type property.

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

Setting container-type: inline-size enables the use of cqi and cqw based on that element's width. For height-based units (cqh and cqb), container-type: size is required, which requires an explicit height on the container to prevent infinite layout loops.

How Nested Resolution Works

When components are nested inside each other, container units resolve against the nearest ancestor that has an active container-type.

Independent Component Scaling

Consider a nested dashboard widget:

<section class="dashboard-widget">
  <article class="nested-card">
    <button class="action-btn">Click Me</button>
  </article>
</section>
.dashboard-widget {
  container-type: inline-size;
}

.nested-card {
  container-type: inline-size;
  padding: 4cqi; /* Scales relative to .dashboard-widget */
}

.action-btn {
  font-size: clamp(0.75rem, 3cqi, 1.25rem); /* Scales relative to .nested-card */
}

In this setup:

  1. .nested-card evaluates 4cqi against the width of .dashboard-widget.
  2. Because .nested-card is also declared as a container, .action-btn evaluates its 3cqi against .nested-card, not the outer .dashboard-widget.

This isolation allows nested elements to scale proportionally to their direct parent layout, avoiding unintended overflows or undersized UI elements.

Targeting Specific Ancestors with Container Names

By default, units reference the closest container. If a nested element must scale based on a container higher up the tree instead of its immediate parent, you can use named containers.

.dashboard-widget {
  container-name: widget;
  container-type: inline-size;
}

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

.action-btn {
  /* Targets the outer widget rather than .nested-card */
  padding: 2cqw widget; 
}

(Note: Named container unit targeting depends on specific browser implementation progress; container queries via @container widget (min-width: ...) are universally supported for conditional styling).

Practical Applications for Nested Scaling

Fluid Typography

Combining clamp() with cqi creates fluid typography that fits inside nested containers without breaking line-height or causing awkward line breaks:

.nested-card h3 {
  font-size: clamp(1rem, 2rem + 2cqi, 2.5rem);
}

Proportional Spacing and Radii

Instead of hardcoding pixels, margins, gaps, and border-radii can scale uniformly:

.nested-card-grid {
  display: grid;
  gap: clamp(8px, 2cqi, 24px);
  border-radius: clamp(4px, 1.5cqi, 16px);
}

Self-Contained Aspect Ratios

When creating components like avatars or media overlays inside complex hierarchies, sizing can be locked directly to the container's inline dimension:

.avatar {
  width: 12cqi;
  height: 12cqi;
  border-radius: 50%;
}

By leveraging cqw, cqh, cqi, and cqb, nested components become truly autonomous, rendering correctly regardless of where they are placed in a design hierarchy.