What if you used Container Units for… everything?

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.

See how the outer border radius’ match, but the inner card are different and look off on the larger card.

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.

Here the text on the larger card feels a bit too big but the tags are OK. The text on the smaller card feels OK, but those tags are 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.

Bonus problem: you can’t use container units to set the grid-template-columns as they can never be based on an element that is reliably the same width as the grid.

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.

Wanna learn CSS from a course?

One response to “What if you used Container Units for… everything?”

  1. yaireo says:

    I was also thinking this, just like I always have been advocating for using em units over powerless fixed 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.

Leave a Reply

Your email address will not be published. Required fields are marked *

Did you know?

Frontend Masters Donates to open source projects. $313,806 contributed to date.