DEV Community

loading...
Cover image for Fluid Typography with CSS Clamp() is My New Favorite Thing

Fluid Typography with CSS Clamp() is My New Favorite Thing

yuschick profile image Daniel Yuschick ・3 min read

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);
}
Enter fullscreen mode Exit fullscreen mode

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.

Demonstrating fluid typography with CSS clamp()

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.

Support for the clamp() function from caniuse.com

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); 
  }
}
Enter fullscreen mode Exit fullscreen mode

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)

pic
Editor guide
Collapse
oenonono profile image
Junk

"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...

Collapse
kwsim539 profile image
Kenneth Sim

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.

Collapse
yuschick profile image
Daniel Yuschick Author

If you haven't already, give that link a read. It may give you some ideas on how to approach this.

Thread Thread
kwsim539 profile image
Kenneth Sim

Cool. Thanks

Thread Thread
oenonono profile image
Junk

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.)

Collapse
yuschick profile image
Daniel Yuschick Author

Hadn't considered this before. Thanks for the link.

Collapse
davidbrear profile image
David Brear

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.

Collapse
jenseoul profile image
Jen

Seems super useful for responsive design! Thanks

Collapse
ben profile image
Ben Halpern

Wow, today I learned about clamp().. Really interesting.

Collapse
briancross profile image
Brian Cross

I use clamp() all the time. Love it.

Collapse
romeoks profile image
Romeo

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.

Collapse
tobto profile image