#212: A note about clamp()

[Robin]: This week I want to take a closer look at the min(), max(), and clamp() functions. I keep hearing things about them but I’ve never used them in production and although these are relatively new features they have pretty dang good browser support at this point so it’s useful to jump in now.

First up: the min() function picks the smallest of the values you pass into it. So, if we were to write something like this:

div {
  width: min(700px, 80%);

This div will then be 700px if that value is smaller than 80%. The other way to think about this is it’s really the same as writing this:

div {
  width: 80%;
  max-width: 700px;

For some reason this one line of CSS makes my mind boggle. But likewise, max() does the opposite of this. So if we were to write:

div {
  width: max(700px, 80%);

Then whichever of these two values is biggest, that’s the value the function will pick. Or you could write that like this:

div {
  width: 80%;
  min-width: 500px;

So it might be useful to see these functions as a short hand for setting min-width and max-width. Except, you don’t have to set these functions on width, you can use these pretty much anywhere you want.

Now what about clamp()? Well, it takes three values: min, max, and preferred value. A popular usage is with font-size:

body {
  font-size: clamp(1.1rem, 1vw + 1.1rem, 2.5rem);

Translation: “I want the text size to be a minimum of 1.1rem and a maximum of 2.5rem. Attempt to size the type with a fluid calculation of 1.1rem plus 1% of the viewport size, but cap it at 2.5rem on the high end and 1.1rem on the low end.” And that looks something like this:

This GIF uses 4vw as the ideal calculation, but for accessibility try to avoid that and factor in a relative unit for all the values of clamp(), like the 1vw + 1.1rem middle parameter of the above code example.

(We cover this in Simplified Fluid Typography.)

This instructs the browser to change the font-size depending on the width of the viewport but also, crucially, it allows us to have a min font size for legibility. This is fantastic because we get so much more control over font-size for design reasons, too. Say I want a different set of typographic relationships on smaller screens than I do on larger ones. With clamp() we can do just that.

I have a feeling that these functions are probably going to be used in a ton of places besides just setting font-size and width but even if that’s not the case—clamp() especially gives us this new typographic superpower that we’ve never really had before. And that’s darn exciting.

Also, on this note, Kevin Powell goes into a lot more depth in his video about these functions. There’s a lot of nuance that I’m skipping over so before you use them then it’s definitely worth checking out Kevin’s video.

I really enjoyed this chat with Chris and Gerry McGovern about all the ways in which the web has gotten worse lately; performance and accessibility specifically. But this is true of all sorts of design problems, too. One point Chris brings up is how difficult changing the TV channel is now; it’s no longer quite so easy as changing the nob on the set, now you need to use an extremely complex remote to pick which app or service you need, etc. etc.

Jay Hoffman published Chapter 2 of his history of the web and I’ll be reading that later this afternoon—I adored the first chapter all about Sir Tim Berners-Lee and his work to create the very foundations of what we call the Web today:

Berners-Lee returned to CERN in a fellowship position in 1984. It was four years after he had left. A lot had changed. CERN had developed their own network, known as CERNET, but by 1989, they arrived and hooked up to the new, internationally standard Internet. “In 1989, I thought,” he recalls, “look, it would be so much easier if everybody asking me questions all the time could just read my database, and it would be so much nicer if I could find out what these guys are doing by just jumping into a similar database of information for them.” Put another way, he wanted to share his own homepage, and get a link to everyone else’s.

This sure is interesting: Halfmoon is a front-end framework with dark mode built in. Tahmid wrote this great post that gives us the elevator pitch about this new framework and then walks through how to get started using it:

Whenever a new framework is introduced, the same question is inevitably pops up: Why did you actually build this? The answer is that I freaking love dark modes and themes. Tools that come with both a light and a dark mode (along with a toggle switch) are my favorite because I feel that being able to change a theme on a whim makes me less likely to get bored looking at it for hours. I sometimes read in dim lighting conditions (pray for my eyes), and dark modes are significantly more comfortable in that type of situation. 

Isn’t this effect pretty neat? The other day I wrote about how to make this stacked card style with a bit of sticky positioning and a dash of Sass. I noticed this effect on the CSS-Tricks website itself and on this charming design in the portfolio of Corey Ginnivan that is much prettier and much more lovely than my demo:

But this is remarkable because not so long ago this would’ve been impossible. And the nifty thing about it is that it has a bit of progressive enhancement built right in: if a browser doesn’t support position: sticky then you can scroll through these items without the stacking effect at all. Yay for progressive enhancement!


Fast authoring of AI-stabilized cross-browser UI tests. Reduce maintenance with automated tests that adjust with code changes.

Get started today for free →

[Chris]: Matt Lacey:

You’ve only added two lines – why did that take two days!

It might seem a reasonable question, but it makes some terrible assumptions:

• lines of code = effort
• lines of code = value
• all lines of code are equal

None of those are true.

Matt lists lots of practical and understandable reasons why a bug fix of only a line or two can sometimes take a long time.

What a nice coincidence that Benjamin Schachter wrote about exactly this situation the other day in What I Learned by Fixing One Line of CSS in an Open Source Project. Ben fixed a weirdly misaligned toggle switch on iOS with one line of CSS, but it took a while to isolate and replicate the problem, and how to actually change that line in development in a way he could test it.