Container queries let a block lay itself out based on the space it was given rather than the size of the browser window — the only way to make one block correct in both a narrow sidebar and a wide content column. A media query cannot tell those apart, because the viewport is the same width in both.
The trap
An element that declares container-type cannot be styled by queries against that container. Only its descendants can.
/* BROKEN: the grid rule never applies */
.block {
container-type: inline-size;
container-name: blk;
}
@container blk (min-width: 520px) {
.block { display: grid; } /* silently ignored */
.block__item { font-size: 1.6rem; } /* works */
}
The cruel part is that rules targeting descendants do apply, so the block half-changes and looks broken rather than unchanged.
The fix
Use two elements: one defines the container, the other is laid out.
.blk__container { container-type: inline-size; container-name: blk; }
@container blk (min-width: 520px) {
.blk__body { display: grid; }
}
Testing it
Asserting that @container appears in the CSS proves nothing — it was there in the broken version too. This is only caught by rendering the block at two widths and looking at it.
Related specificity trap
Inside a container block, a bare .blk__value has the same specificity as .blk__value--name. Coming later in the stylesheet, it wins. Use .blk__value:not(.blk__value--name) when the modifier must survive.
Recommended Comments