Tailwind Container Query Units: cqw, cqh and cqi in Practice
AI generated
tw
Tailwind CSS · Container Queries · Responsive Design
Container Query Units in Tailwind
Putting cqw, cqh and cqi to work instead of tying components to the viewport

Viewport units like vw and vh have a structural problem: they only know the size of the browser window, not the size of the container a component actually lives in. Container query units solve exactly that, computing sizes relative to the nearest ancestor with container-type set. Combined with the native @container utilities in Tailwind v4, this makes it possible to build components that behave correctly regardless of the surrounding layout, whether they end up in a narrow sidebar or a wide main content area.

16 min read cqw · cqh · cqi @container Tailwind v4

1. What container query units are and which problem they solve

Container query units are length units that do not refer to the browser window, but to the size of the nearest ancestor element marked as a query container. While vw and vh always take the full width and height of the visible viewport as their reference, regardless of where a component actually sits in the layout, cqw and cqh compute relative to exactly the container the element is nested inside. That sounds like a minor nuance at first, but it fundamentally changes how reusable components can be built.

The classic problem shows up with a card component that needs to appear both in a narrow sidebar and in a wide main content area of the same page. With viewport units, the card gets the same font size in both cases, because the viewport stays identical even though the available space is completely different. With container query units, font size instead adapts automatically to the actual width of its respective container, regardless of how large the browser window happens to be or how deeply the component is nested in the layout.

2. cqw, cqh, cqi, cqb, cqmin and cqmax in detail

cqw equals one percent of the container width, cqh one percent of the container height, both relative to the nearest ancestor with container-type set. Alongside those there are the logical variants cqi (inline-size, the width along the horizontal writing direction) and cqb (block-size, the height along the block direction), which matter for vertical writing modes but in everyday work with Latin script usually match cqw and cqh exactly. In practice, cqi is often preferred over cqw because it combines more cleanly with logical properties like margin-inline.

cqmin and cqmax take the smaller and larger value out of a container's width and height respectively, similar to how vmin and vmax work for the viewport. That is useful whenever a size should depend on neither the width nor the height alone, for example a square icon container whose icon size should follow whichever dimension is smaller, so it never overflows the edge regardless of whether the container ends up wider or taller.


/* Base units */
.card-title {
  font-size: 5cqi;   /* 5% of the container's inline size */
}

.card-icon {
  width: 8cqmin;       /* follows whichever container dimension is smaller */
  height: 8cqmin;
}

3. Setting container-type: the prerequisite for every container query unit

Container query units only work inside an element whose ancestor has been explicitly marked as a container, through the CSS property container-type. Without that marking, the units fall back to their default behavior and effectively act as 0, which in practice usually leads to an invisible or incorrectly scaled element. In Tailwind v4, the utility class @container on the desired ancestor element is enough to set container-type: inline-size, the value that fits most horizontally scaling layouts.

It matters that the container ancestor does not have to be the direct parent element, but rather the nearest ancestor in the DOM hierarchy carrying the marking. That makes it possible to set a container further up the tree and let several nested child elements benefit from the same container query units simultaneously, without every intermediate level needing to be declared a container itself. That flexibility is exactly what makes container queries practical for complex, multi-level component structures.

4. Practical example: font size in a reusable card component

A product card rendered both in a narrow 280 pixel sidebar and in a wide 900 pixel main content area needs appropriately proportioned typography in both contexts. With @container on the enclosing grid element and cqi-based font sizes on the card title, typography scales automatically with the actually available width, without writing a dedicated breakpoint rule for every possible placement.

The decisive difference from a pure media-query solution shows up as soon as the same card is embedded in two places on the page at once, say the sidebar and the main content area. A media query can only react to the size of the entire viewport and would assign both instances the same font size, even though their containers are completely different widths. Container query units instead compute individually for each instance relative to its own container, so both cards stay correctly proportioned at the same time.