Published October 10, 2026
CSS clamp() with container query units fixes the most annoying property of fluid type: viewport units do not know where the component lives. A card in a 300 pixel sidebar gets the same font-size as a card in a 1200 pixel hero if your clamp() is built on vw. Swap the vw for cqw and the type scales to its container instead of the screen.
The syntax needs no introduction if you have used clamp() before: clamp(minimum, preferred, maximum). The preferred value is where the fluidity lives. Traditionally that preferred value is written with vw, as in clamp(1rem, 0.975rem + 0.125vw, 1.125rem). Replace the vw with a container query unit and the same formula now responds to the container. For a card heading that might read clamp(1.25rem, 1rem + 2cqw, 1.75rem). Same math, different reference point.
The one setup step everyone skips
Container query units resolve against the nearest ancestor with container-type set, almost always container-type: inline-size. Without that declaration on a wrapper, cqw falls back to the small viewport width, and your carefully computed fluid type behaves exactly like vw. That is the single most common bug in clamp() plus container unit code: the clamp looks right, the values compute, and the type responds to the browser window instead of the card. If your fluid type is ignoring the layout, check the container declaration first.
.card-grid {
container-type: inline-size;
}
.card h2 {
font-size: 1.5rem; /* fallback for older browsers */
font-size: clamp(1.25rem, 1rem + 2cqw, 1.75rem);
}
.card {
padding: clamp(1rem, 4cqi, 2rem);
}
Note the static font-size on the line above. Older browsers ignore declarations they do not understand, so a plain rem size there gives them something sane while modern browsers use the clamp. Container queries are baseline widely available since early 2023 (Chrome 105+, Edge 105+, Firefox 110+, Safari 16+), and clamp() itself has been supported in all major browsers since 2020, so this fallback mainly serves the stragglers.
cqw vs. cqi, and which to reach for
cqw is 1 percent of the query container's width. cqi is 1 percent of the query container's inline size. In left-to-right horizontal writing those are the same number, which is why most examples use them interchangeably. They diverge in vertical writing modes, where the inline axis is vertical. If your components need to survive internationalization, prefer cqi; it follows the writing mode automatically. The full family is cqw, cqh, cqi, cqb, cqmin, and cqmax, but cqi covers nearly all type work.
The same technique extends past type. Padding that scales with the card (clamp(1rem, 4cqi, 2rem)), gaps between grid children, even border radii all behave better when they are sized in container units instead of fixed rems or viewport units. A component that carries its own responsive behavior inside clamp() is a component that looks right dropped into a sidebar, a hero, or a modal without extra breakpoint overrides.
There is a design judgment buried in this, though. Container-relative type means two instances of the same component can render at different sizes on the same page. That is the point, but it also means your type scale is no longer a fixed ladder. Keep the min and max bounds honest: the clamp's floor protects readability in narrow slots and the ceiling keeps a hero card from shouting. Pick those two numbers from your actual layout extremes, then let the fluid middle do its job.
Frequently asked questions
What is the difference between cqw and cqi in clamp()?
cqw is 1 percent of the query container's width. cqi is 1 percent of its inline size. They match in left-to-right horizontal writing but differ in vertical writing modes, so cqi is the safer choice for internationalized components.
Do I need container-type for cqw to work in clamp()?
Yes. Without container-type: inline-size (or another container type) on an ancestor, container query units resolve against the small viewport, and your clamp behaves like a vw-based one. This is the most common setup bug.
What is the browser support for clamp() with container query units?
clamp() itself works in all major browsers since 2020. Container query units need browsers from early 2023 or later (Chrome 105+, Edge 105+, Firefox 110+, Safari 16+). Put a static font-size declaration on the line above as a fallback.
Why use cqw instead of vw inside clamp()?
Because vw tracks the whole viewport. A card in a narrow sidebar gets the same vw-driven size as a card in a wide hero. cqw tracks the card's container, so each instance of a component sizes itself to where it actually lives.
Can I use cqw inside calc() too?
Yes. Container query units work anywhere a length works, so calc(1rem + 1.25cqw) is valid. The same container-type and fallback rules apply.
Work out your own clamp values first.