CSS doesn’t have max-font-size
, so if we need something that does something along those lines, we have to get tricky.
Why would you need it at all? Well, font-size
itself can be set in dynamic ways. For example, font-size: 10vw;
. That’s using “viewport units” to size the type, which will get larger and smaller with the size of the browser window. If we had max-font-size
, we could limit how big it gets (similarly the other direction with min-font-size
).
One solution is to use a media query at a certain screen size breakpoint that sets the font size in a non-relative unit.
body {
font-size: 3vw;
}
@media screen and (min-width: 1600px) {
body {
font-size: 30px;
}
}
There is a concept dubbed CSS locks that gets fancier here, slowly scaling a value between a minimum and maximum. We’ve covered that. It can be like…
body {
font-size: 16px;
}
@media screen and (min-width: 320px) {
body {
font-size: calc(16px + 6 * ((100vw - 320px) / 680));
}
}
@media screen and (min-width: 1000px) {
body {
font-size: 22px;
}
}
We’ve also covered how it’s gotten (or will get) a lot simpler.
There is a max()
function in CSS, so our example above becomes a one-liner:
font-size: max(30vw, 30px);
Or double it up with a min and max:
font-size: min(max(16px, 4vw), 22px);
Which is identical to:
font-size: clamp(16px, 4vw, 22px);
Browser compatibility for these functions is pretty sparse as I’m writing this, but Chrome currently has it. It will get there, but look at the first option in this article if you need it right now.
Now that we have these functions, it seems unlikely to me we’ll ever get min-font-size
and max-font-size
in CSS, since the functions are almost more clear as-is.
Agree. Mathematical functions that can be applied to size values in standard properties make much more sense than bespoke min-* and max-* properties. Heck, all of the redundant properties that currently exist ought to be deprecated once the clamp function is widely supported.
Great article as always, Chris.
Just a sidenote on the one-liner version with clamp() — using viewport units as the preferred value, you aren’t able to control the rate at which the text resizes.
So you might want to combine clamp() with the CSS locks technique, and with a tiny bit of custom properties you can even omit the need for media queries quite easily:
Please be careful with maximum text size, particularly on sites/pages that face the general public or employees. If you prevent the text from scaling up 200%, then that is a WCAG SC 1.4.4 failure at Level AA. Viewport units have their own call-out as a major risk in WCAG.
No matter what technique you use, be sure that the page text can be zoomed at least 200%. And yes, I have written about responsive type and zoom, and have cautioned against
min()
,max()
, andclamp()
.