CSS Container Queries are nonetheless gaining traction and many people are getting our fingers moist with them, even when it’s for little experiments or whatnot. They’ve received nice, however not fairly full, browser assist — sufficient to justify utilizing them in some tasks, however possibly to not the extent the place we is likely to be tempted to begin changing media queries from previous tasks with shiny new container dimension queries.
They certain are useful although! In truth, I’ve already run into a couple of conditions the place I actually needed to succeed in for them however simply couldn’t overcome the assist necessities. If I had been in a position to make use of them, that is how it will have regarded in these conditions.
All the following demos can be finest considered in Chrome or Safari on the time of this writing. Firefox plans to ship assist in Model 109.
Case 1: Card grid
You sort of needed to count on this one, proper? It’s such a standard sample that each one of us appear to run into it sooner or later. However the reality is that container dimension queries would have been an enormous time-saver for me with a greater end result had I been in a position to make use of them over customary media queries.
Let’s say you’ve been tasked with constructing this card grid with the requirement that every card must hold it’s 1:1 side ratio:
It’s more durable than it seems to be! The issue is that sizing a element’s contents on the viewport’s width leaves you on the mercy of how the element responds to the viewport — as effectively the way in which every other ancestor containers reply to it. If, for instance, you need the font dimension of a card heading to scale back when the cardboard hits a sure inline dimension there’s no dependable solution to do it.
You may set the font dimension in vw
items, I suppose, however the element remains to be tied to the browser’s viewport width. And that may trigger issues when the cardboard grid is used different in contexts that will not have the identical breakpoints.
In my real-world challenge, I landed on a JavaScript method that will:
- Hear for a resize occasion.
- Calculate the width of every card.
- Add an inline font dimension to every card primarily based on its width.
- Model all the pieces inside utilizing
em
items.
Looks as if lots of work, proper? However it’s a steady answer to get the required scaling throughout totally different display sizes in numerous contexts.
Container queries would have been so significantly better as a result of they supply us with container question items, such because the cqw
unit. You most likely already get it, however 1cqw
is the same as 1%
of a container’s width. We even have the cqi
unit that’s a measure of a container’s inline width, and cqb
for a container’s block width. So, if we now have a card container that’s 500px
huge, a 50cqw
worth computes to 250px
.
If I had been in a position to make use of container queries in my card grid, I might have arrange the .card
element as a container:
.card {
container: card / dimension;
}
Then I might have set an interior wrapper with padding
that scales at 10%
of the .card
‘s width utilizing the cqw
unit:
.card__inner {
padding: 10cqw;
}
That’s a pleasant solution to scale the spacing between the cardboard’s edges and its contents constantly regardless of the place the cardboard is used at any given viewport width. No media queries required!
One other thought? Use cqw
items for the font dimension of the interior contents, then apply padding in em
items:
.card__inner {
font-size: 5cqw;
padding: 2em;
}
5cqw
is an arbitrary worth — only one that I settled on. That padding remains to be equal to 10cqw
for the reason that em
unit is relative to the .card__inner
font dimension!
Did you catch that? The 2em
is relative to the 5cqw
font dimension that’s set on the identical container. Containers work totally different than what we’re used to, as em
items are relative to the identical aspect’s font-size worth
. However what I shortly observed is that container question items relate to the closest father or mother that can also be a container.
For instance, 5cqw
doesn’t scale primarily based on the .card
aspect’s width on this instance:
.card {
container: card / dimension;
container-name: card;
font-size: 5cqw;
}
Fairly, it scales to regardless of the nearest father or mother that’s outlined as a container. That’s why I arrange a .card__inner
wrapper.
Case 2: Alternating format
I wanted yet one more card element in a distinct challenge. This time, I wanted the cardboard to transition from a panorama format to a portrait format… then again to panorama, and again to portrait once more because the display will get smaller.
I did the soiled work of creating this element go to portrait at these two particular viewport ranges (shout out to the new media question vary syntax!), however once more, the issue is that it’s then locked to the media queries set on it, its father or mother, and the rest that may reply to the viewport’s width. We would like one thing that works in any situation with out worrying about questioning the place the content material goes to interrupt!
Container queries would have made this a breeze, due to the @container
rule:
.info-card {
container-type: inline-size;
container-name: info-card;
}
@container info-card (max-width: 500px) {
.info-card__inner {
flex-direction: column;
}
}
One question, infinite fluidity:
However maintain on! There’s one thing you would possibly need to be careful for. Particularly, it may very well be tough to make use of a container question like this inside a prop-based design system. For instance, this .info-card
element might include baby elements that depend on props to alter their look.
Why’s {that a} large deal? The cardboard’s portrait format would possibly require the alternate styling however you possibly can’t change JavaScript props with CSS. As such, you danger duplicating the required types. I truly touched on this and the right way to work round it in one other article. If you must use container queries for a big quantity of your styling, then you could must base your complete design system round them moderately than making an attempt to shoehorn them into an current design system that’s heavy on media queries.
Case 3: SVG strokes
Right here’s one other tremendous widespread sample I’ve just lately used the place container dimension queries would have resulted in a extra polished product. Say you’ve got an icon locked up with a heading:
<h2>
<svg>
<!-- SVG stuff -->
</svg>
Heading
</h2>
It’s fairly simple to scale the icon with the title’s dimension, even with out media queries. The issue, although, is that the SVG’s stroke-width
would possibly get too skinny to be observed all that effectively at a smaller dimension, and maybe catch an excessive amount of consideration with a brilliant thick stroke at a bigger dimension.
I’ve needed to create and apply lessons to every icon occasion to find out its dimension and stroke width. That’s OK if the icon is subsequent to a heading that’s styled with a set font dimension, I assume, nevertheless it’s not so nice when working with fluid kind that continuously modifications.
The heading’s font dimension is likely to be primarily based on the viewport’s width, so the SVG icon wants to regulate accordingly the place its stroke works at any dimension. You may make the stroke width relative to the heading’s font-size
by setting it in em
items. However when you’ve got a selected set of stroke sizes that you must persist with, then this wouldn’t work as a result of it in any other case scales linearly — there’s no solution to modify it to a selected stroke-width
worth at sure factors with out resorting to media queries on the viewport width.
However right here’s what I’d have accomplished if I had the posh of container queries at the moment:
.icon {
container: icon / dimension;
width: 1em;
peak: 1em;
}
.icon svg {
width: 100%;
peak: 100%;
fill: none;
stroke: #ccc;
stroke-width: 0.8;
}
@container icon (max-width: 70px) {
.icon svg {
stroke-width: 1.5;
}
}
@container icon (max-width: 35px) {
.icon svg {
stroke-width: 3;
}
}
Evaluate the implementations and see how the container question model snaps the SVG’s stroke to the precise widths I would like primarily based on the container’s width.
Bonus: Different kinds of container dimension queries
OK, so I haven’t truly run into this on an actual challenge. However as I used to be combing by means of data on container queries, I observed that there are further issues we are able to question on a container which are associated to the container’s dimension or bodily dimensions.
Most examples I’ve seen question the width
, max-width
, and min-width
, peak
, block-size
, and inline-size
as I’ve been doing all through this text.
@container info-card (max-width: 500px) {
.info-card__inner {
flex-direction: column;
}
}
However MDN outlines two extra issues we are able to question towards. One is orientation
which makes excellent sense as a result of we use it on a regular basis in media queries. It’s no totally different with container queries:
@media display (orientation: panorama) {
.info-card__inner {
/* Model away! */
}
}
@container info-card (orientation: panorama) {
.info-card__inner {
/* Model away! */
}
}
The opposite? It’s aspect-ratio
, consider it or not:
@container info-card (aspect-ratio: 3/2) {
.info-card__inner {
/* Model away! */
}
}
Right here’s an editable demo to mess around with each examples:
I haven’t actually discovered an excellent use case for both of those but. When you have any concepts or really feel prefer it might’ve helped you in your tasks, let me know within the feedback!