Using Container Query Units Relative to an Outer Container
Using Container Query Units Relative to an Outer Container 관련
Recently, Matt Wilcox posted on Mastodon:
The fact you can’t specify which container 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 to this container; 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 this interactive guide by 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 since they 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 its content-box
dimensions). The problem is, if we do something like this (a 20cqw
light blue strip at the start of the gradient going towards 3 o’clock):
.inner-child {
background: linear-gradient(90deg, #0a9396 20cqw, #0000)
}
… then the 20cqw
value is 20%
(a fifth) of the content-box
width of the .inner-container
. This can be seen below, where we have purple guidelines 20%
of the width apart.

what 20cqw represents
But what we want is for that 20cqw
value to be 20%
of the content-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 the width
of the .outer-container
(which isn’t the nearest container for .inner-child
) is situated relative to the 500px
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, we are getting closer!
What if we move the --s
variable uspstream? After all, a 20cqw
length value set on the .inner-container
is 20%
of the content-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 similar background
restricted to 20cqw
from the left along the x axis and make the .inner-child
semi-transparent, just to check if the --s
values overlap (which is what we want, --s
being 20%
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
the 20cqw
of the --s
is taken to be 20%
of the content-box
width of its nearest container, .outer-container
(dashed dark blue boundary). However, for the .inner-child
, the 20cqw
of the --s
aren’t taken to mean the same value. Instead, they are taken to mean 20%
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?