According to Twitter, which is definitely an accurate representation of real life, I’m in the extreme minority of developers who actually enjoy CSS. I got into development (all those years ago) by way of design and as a designer first, working in CSS unlocked so much creative potential.
As the web shifted into a more fluid experience (all those years ago), things like Flexbox and Grid blew my mind with their incredible potential for responsive design. And on a smaller scale, this little CSS function has done the same thing recently.
CSS Clamp()
The clamp()
function seems small but wields incredible power by clamping a value between an upper and lower range. Think minmax()
but for more than rows and columns.
The first place I found the value of clamp()
was font sizes.
Fluid typography can get a bit complicated for me. Running various calculations around a viewport size had me feeling both uncertain and imprecise because the code didn’t tell me what size the font would actually be. And I couldn’t always account for display extremes.
But clamp()
provides that same fluidity with better control and readability.
h1 {
font-size: clamp(1.75rem, 3vw, 2.1rem);
}
Let’s break down what this function does.
The clamp()
functions takes three values:
- A minimum value
- A preferred value
- A maximum value
With those values in mind, you can see the code snippet above defines the minimum size as 1.75rem
and the maximum size as 2.1rem
. In my designs from mobile on up, I don’t want my h1
font to ever fall outside of that range.
The fluidity comes into play by setting the middle value, the preferred size, to a dynamic value. I like to use vw
units that allow the font to scale with the size of the display but stay within the range of 1.75rem
to 2.1rem
.
With the clamp()
values defined, I tested the h1
element by dragging my browser smaller and larger and watched as the font size scaled smoothly within its range.
Admittedly, it’s a small size range but I now feel more in control of how text will behave in my projects.
But while we’re at it, why stop at text? I’ve found several other uses for clamp()
such as border sizes, padding values, and even element widths. Maybe a bit overboard but development should be fun and this little function brought the fun in spades.
Browser Support (Looking at you, Safari!)
Update 21.3.21: Browser support has expanded and standardized since originally writing this article to include more recent versions of Safari. The remainder of this section, though, is still written based on the lack of Safari support.
Nothing good is easy and when I tested my site in Safari, I was reminded of that when everything appeared janky.
Some browsers are yet to support clamp()
but luckily, there are two other small, clutch functions– min()
and max()
we can use. When put together, they can provide similar functionality to clamp()
but also play nicely with additional browsers.
h1 {
font-size: clamp(1.75rem, 3vw, 2.1rem);
@supports not (font-size: clamp(1.75rem, 3vw, 2.1rem)) {
font-size: min(max(1.75rem, 3vw), 2.1rem);
}
}
From the code snippet you can see that when combined, min()
and max()
behave very similarly to clamp()
but where clamp()
is available, I prefer it.
Sure, you could argue this article should be titled Fluid Typography with CSS min() & max() is My New Favorite Thing. That’s fair. But I came across clamp()
first, so it feels more like the feature while min()
and max()
feel more like the fallback. I do prefer the readability of clamp()
though, and prefer writing only one function to nesting two together.
Preferences aside, I’m happy to feel more in control of fluid typography now and I have clamp()
to thank.
Discussion (12)
"When people zoom a page, it is typically because they want the text to be bigger. When we anchor the text to the viewport size, even with a (fractional) multiplier, we can take away their ability to do that. It can be as much a barrier as disabling zoom. If a user cannot get the text to 200% of the original size, you may also be looking at a WCAG 1.4.4 Resize text (AA) problem"
adrianroselli.com/2019/12/responsi...
Good to know. I was so excited to implement this on my next project, but sadly the projects I work on must be ADA compliant.
If you haven't already, give that link a read. It may give you some ideas on how to approach this.
Cool. Thanks
Yep, I think it's still possible, just not as easy as we all initially hoped. The constraint is ensuring that zooming in twice causes the font-size to be twice it's initial size, but for other reasons the viewport gets special treatment of it's size and therefore calculations of viewport units when zooming that makes that very hard to do. (It's kinda like how the body element's background gets that special treatment. There's good reasons. But it gets in the way here.)
Hadn't considered this before. Thanks for the link.
People who “hate” css are just bad at it and would rather complain than get better at it. It’s trendy to hate CSS and when I hear people trash it, I just feel bad for them that they’re so bad at development.
Clamp seems cool and I feel like the jankiness of safari not smoothly changing the font size is only viewed when resizing your browser which .01% of actual users will do.
Seems super useful for responsive design! Thanks
Wow, today I learned about
clamp()
.. Really interesting.I use clamp() all the time. Love it.
Wouldn't be easier to work with vw? Except mobile queries.
Let's say we add a breakpoint at 1440px with margin auto for everything that's 1440px and more. And for everything that falls under 1439px we transform into px = vw (for 1439px viewport).
Than we would have the same layout for desktops, laptops etc.
Again except mobile resolutions, although we can use vw for mobile layouts because it would more fluid since mobile resolutions are constantly changing.
Super