Using Container Query Units Relative to an Outer Container
Using Container Query Units Relative to an Outer Container êŽë š
Recently, Matt Wilcoxposted on Mastodon:
The fact you canât specifywhichcontainer for container query units is a ballache. The moment you have nested containers youâre [screwed]; because if you want the calculated gap from the rowâs container; but youâre inside a nested container⊠tough. Your units are wrong. And you canât just say âno; not relative tothiscontainer; relative to the named outer container!â
First off, if youâre not familiar with container queries and container query units, you can check out one of the many resources on the topic, for example thisinteractive guideby Ahmad Shadeed, which I believe is the most recent out of all the detailed ones Iâve seen. As always, the date of the resources used is important for web stuff, especially since these units in particular have changed their name sincethey were first proposed (w3c/csswg-drafts
)and we got an early draft of the spec.
Now, the problem at hand: letâs say we have an.inner-container
inside an.outer-container
â they are both made to be containers:
[class*='container'] { container-type: size }
We want any.inner-child
of the.inner-container
to be able to use length values set in container query units relative to the.outer-container
(more precisely, to itscontent-box
dimensions). The problem is, if we do something like this (a20cqw
light blue strip at the start of the gradient going towards 3 oâclock):
.inner-child {
background: linear-gradient(90deg, #0a9396 20cqw, #0000)
}
⊠then the20cqw
value is20%
(a fifth) of thecontent-box
width of the.inner-container
. This can be seen below, where we have purple guidelines20%
of the width apart.

what 20cqw represents
But what we want is for that20cqw
value to be20%
of thecontent-box
width of the.outer-container
.
Strictly for the queries themselves, we could do something like this:
.outer-container { container: outer/ size }
.inner-container { container: inner/ size }
@container outer (min-width: 500px) {
.inner-child { background: darkorange }
}
This allows us to set certain styles on the.inner-child
elements based on where thewidth
of the.outer-container
(which isnât thenearestcontainer for.inner-child
) is situated relative to the500px
threshold.
But we cannot do something like this to specify which container should be the one that the query units used on.inner-child
are relative to:
.inner-child {
/* can't do this */
background: linear-gradient(90deg, #0a9396 outer 20cqw, #0000)
}
Nor can we do this:
.inner-child {
/* can't do this either */
--s: outer 20cqw;
background: linear-gradient(90deg, #0a9396 var(--s), #0000)
}
However, wearegetting closer!
What if we move the--s
variable uspstream? After all, a20cqw
length value set on the.inner-container
is20%
of thecontent-box
width of its nearest container, which is the.outer-container
. This would mean our code becomes:
[class*='container'] { container-type: size }
.inner-container {
--s: 20cqw;
background:
repeating-linear-gradient(45deg, #bb3e03 0 5px, #0000 0 1em)
0/ var(--s) no-repeat
}
.inner-child {
background:
linear-gradient(90deg, #0a9396cc var(--s), #0000)
}
We also give the.inner-container
a similarbackground
restricted to20cqw
from the left along thexaxis and make the.inner-child
semi-transparent, just to check if the--s
values overlap (which is what we want,--s
being20%
or a fifth of the.outer-container
width). However,this fails (thebabydino
), as it can be seen below:

20cqw
. However, the container query units are relative to the outer container only for the inner container, the container query units used on its child being still relative to the inner container (one fifth of its content-box
width).For the.inner-container
the20cqw
of the--s
is taken to be20%
of thecontent-box
width of its nearest container,.outer-container
(dashed dark blue boundary). However, for the.inner-child
, the20cqw
of the--s
arenât taken to mean the same value. Instead, they are taken to mean20%
of the.content-box
width of the.inner-container
(dotted dark red boundary).
Boo!
But what happens if we also register--s
?
@property --s {
syntax: '<length>';
initial-value: 0px;
inherits: true
}
Bingo,this works (thebabydino
)!

I hope youâve enjoyed this little trick.
Where would you use this?