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:
.nested-cardevaluates4cqiagainst the width of.dashboard-widget.- Because
.nested-cardis also declared as a container,.action-btnevaluates its3cqiagainst.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.