📝 CSS-Tricks 260: The Maybe Future Magic of CSS Query Units

View this newsletter on the web.

[Robin]: Have you ever heard of CSS query units? They aren’t a thing in CSS just yet, but let me set the stage to explain exactly how they would be useful. I only stumbled across the idea because I bumped into an interesting problem when it comes to setting type on the web.

I was messing around with the fonts on a project and realized that there are a lot of ways to set the font-size of an element:

.element { font-size: 16px; } .element { font-size: 1em; } .element { font-size: 10vw; } .element { font-size: 10ch; } .element { font-size: 2pt; } .element { font-size: 60ex; }

These are collectively known as the lengths of CSS but they all fall short in an important way because sometimes when I’m setting the font-size of an element—especially when it comes to headings—I’d like to set the font-size based on the width of the parent element.

The examples I’ve seen for container queries, although not in browsers yet, could partially help solve this problem. Let’s say we have some HTML such as this…

<div class="container"> <h1>Title</h1> </div>

In the future, we’ll be able to write the following CSS…

.container { contain: layout inline-size; } @container (width > 40em) { h1 { font-size: 1.5em; } }

This CSS allows us to set the font-size of the <h1> when the container itself reaches a certain width breakpoint. However! Even though I would be thrilled if we got container queries tomorrow, this doesn’t quite solve my problem.

Let’s say I want this headline on the left to only change its font-size based on the width of the div that wraps it (that gray box):

Today we’d have to use something like Fittext.js to detect when the parent element changes size and then jump in and change the font-size of that text.

Sure, we could use a variable unit like this…

h1 { font-size: 20vw; }

…but that will make the heading keep scaling up and up if the width of the browser window increases. Alternatively, we could use the ever-so-good clamp() CSS function and set a min, ideal, and max font-size on the text:

h1 { font-size: clamp(1rem, -0.875rem + 8.333vw, 3.5rem); }

This is very smart and worth keeping in our back pocket but it still doesn’t do quite what I’d like to do. I just want the text to scale up in relation to the parent element.

And this is where CSS query units like qh and qw come in. Although only in a draft spec right now and not any browsers, at some point in the future, we might be able to write CSS like this:

/* All this is likely to change, but the spirit is here. */ div { contain: layout inline-size; } @container (width > 20em) { h1 { font-size: calc(30qw); } }

This will change the size of the <h1> to scale in proportion to the width of that <div> above. Perfect! This is exactly what I was thinking of. And I think the reason I’m so excited about this is that it is a relatively simple thing in print but, today on the web, it’s way, way harder than it needs to be.

I know I’ve only touched on font-size here but I can imagine all sorts of other purposes for scaling an element with qh, qw, or the other units that are available. And perhaps these units never land in browsers, but regardless—it’s truly exciting stuff, in this humble blogger’s opinion, and it solves a real problem that I have with CSS today.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s