I said to myself I said what if I used container units for every single unit in a design? I was wondering, partially because I thought the answer might be well, everything will probably scale really nicely then. Container units, in case you haven’t heard of them, are unit (like px
or rem
, but more closely related to viewport units like vw
or vi
) that are sized relatively to the container that they are in.
Turns out, surprise surprise, that it’s not that easy. There are plenty of things that container queries are awkward at or just not the right unit for.
I had a play with a pretty simple grid of cards of various sizes. Don’t consider this demo in good shape, it’s just what I used to have a plan.
Potential Problem: You Can’t Style The Element You Query
This is a fairly known thing with container queries, but the weirdness with it compounds a bit with container units, as the desire to use those units right away on a container is strong. To be clear, the container units will “work”, they’ll just be based on the next-higher-up container, which if there isn’t a declared one will be the document.
.card-wrap {
container: cardWrap / inline-size;
padding: 2cqi;
border-radius: 4cqi;
.card {
border-radius: 4cqi;
}
}
Code language: CSS (css)
Above, the border-radius
will be different despite looking like it will be the same, because the container the units reference are different.
Potential Solution: Style Nothing on the Container
Be vigilant! It will save headaches if you are hardfast when you set a container
you do no other size-based styling. If that means adding an extra otherwise meaningless <div>
wrapper, well, that’s not ultra ideal as DOM weight does matter, but it’s probably fine.
Potential Problem: Too Small & Too Big
If you only use container units for something like font-size
, it’s pretty easy to get into a situation where text, and text-based elements, end up either too big or too small.
Either is annoying, but too small is also an accessibility failure.
Using container units (or viewport units) alone is a bad practice for text sizing. It’s fixable though.
Potential Solution: Clamp
Making sure text doesn’t get too small or too big is solved with a CSS clamp()
function. And while we’re at it, we can sprinkle in a relative unit to make sure that users font sizing preferences are honored.
You can still use container units, but set those limits and use a bit of relative mixed in.
.tag {
/* Don't */
font-size: 4cqi;
/* Do */
font-size: clamp(16px, 4cqi + 0.5rem, 24px);
}
Code language: CSS (css)
Potential Problem: Rows vs Columns
One strong use case for a container query is shifting layout at container based breakpoints. If that container goes from wide-and-short to narrow-and-tall, then the width-based (probably the most common) container units will be super different.
Say the container here is the card itself, and you size some icons to work with that context when they are horizontal. But then if you shift the layout to a narrow column for the icons, as the card gets bigger, the sizing doesn’t work in that context now.
Instead, if we make the element around the icons the container, and thus it changes width when the layout changes, the change in our icon size can be too dramatic.
Potential Solution: Use a Different Unit
And here’s the rub. You just don’t have to use container units for everything. I doubt anyone ever intended for them to be used that way. It’s just a fun exercise, especially as strong scalability is a great effect.
In this case maybe something like cqmax
units would be workable, so the unit is based on the containers longest edge.
.actions {
container: actions / inline-size;
svg {
display: block;
width: 4cqmax;
min-width: 24px;
max-width: 100%;
aspect-ratio: 1;
}
}
Code language: CSS (css)
But… nah. It’s too weird. I’d say just use relative units or pixels or something here.
In the end, if container units are helpful for a scaling effect based on the size of an element you want to achieve, go for it! The support is good. But don’t force it.
If you’re up for a challenge, have a play with it. Try something like converting every unit in a more complex layout like this into containers with container units.
I was also thinking this, just like I always have been advocating for using
em
units over powerlessfixed units
precisely because of their inheritance powers which gives flexibility.One huge problem with elements with
container
property is they loose the ability to size themselves according to their contents, which is a huge blocker for some designs.I just had a case like that last week and with deep sadness I had to delete the
container
property and resort to javascript resize-observer instead.