Container Query for âis there enough space outside this element?â
Container Query for âis there enough space outside this element?â êŽë š
Say you had a UI component that had pagination arrows for whatever reason. If there was enough space on the outside of that component, you wanted to put those arrows outside, like this this:

But if there isnât enough room for them without shrinking the main content area, then place them inside, like this:

You could do that with plenty of magic numbers, especially in how big the main content area is. But wouldnât it be cool if you didnât have to know? Like the main content area could be whatever, fluid/responsive/flexible, and you could still test if there is âroomâ outside for the arrows or not.
Note
I was playing with this trick because I remember Adam Argyle talking about it one time, but couldnât find where he used it. So I wrote this article up to re-learn and document it. Then of course I find the original article. So full credit to Adam here. Mine approach here is super similar of course. I think I prefer how his @container
query uses cqi
units inside of it in case the parent isnât the viewport. Clever.
The trick is in combining viewport units within a container query. You could probably do it by using container units within a media query too, but weâll go with the former because I tried it and it worked.
Weâre going to need a âwrapperâ element because thatâs just how @container
queries tend to be most useful. You canât query the same element that is the container, so easier if the container is a wrapper.
<div class="box">
<div class="box-inner">
<div class="arrow arrow-left">
<svg ...></svg>
</div>
<div class="arrow arrow-right">
<svg ...></svg>
</div>
</div>
The box will be the container:
.box {
container: box / inline-size;
inline-size: min(500px, 100vw);
}
I love using that second declaration, which says: âMake the element 500px wide, but if the entire browser window is smaller than that, do that instead.â That element is the container.
Then we can use a @container
query on the inside. If we wanted to make a style change exactly when the container is the same size as the browser window, we could do this:
.box-inner {
background: rebeccapurple;
...
@container box (inline-size >= 100vw) {
background: red;
}
}
That will do this!
But weâre actually dealing with the arrows here, so what we want to know is âis there enough space outside for them?â Meaning not the exact size of the element, but that:
Element <= Viewport - Arrows - Gap
Which we can express like this:
.box-inner {
background: rebeccapurple;
...
@container box (inline-size <= calc(100vw - 80px * 2 - 1rem * 2)) {
/* move arrows here */
}
}
Iâll use a bit of translate
to move the arrows here:
And hereâs a video of the success:
Again whatâs kinda cool about this is that we donât know what the size of the container is. It could be changed anytime and this will continue to work. The only hard coded numbers we used were for the size of the arrow elements and the gap, which you could abstract out to custom properties if you wanted to be more flexible.