
Visualizing Responsive Typography
Visualizing Responsive Typography 관련
There are multiple tools that can help create a fluid font-size calculation for CSS – generally expressed as a clamp() function combining em (or rem) with vw (or vi) units. But the results are difficult to understand at a glance, so I wanted to visualize what’s going on, and how the various units interact.
This post is part of a series on revisiting fluid typography:
The simplest interaction between font-size and viewport width would be a 1-to-1 relationship – keeping the values equal at all times. We can express that in CSS as a font-size of 100vw.
html { font-size: 100vw; }
That’s very direct and simple, but a terrible idea. When the viewport width is 0px, the font-size is also 0px. If the viewport grows to be 3250px, the font-size will also be 3250px. The viewport can’t go below 0px, but (in theory) there’s no upper limit here.
Tools like Utopia.fyi will give you a more complex output with several parts:
:root {
--step-0: clamp(1.125rem, 1.0739rem + 0.2273vw, 1.25rem);
}
I built a Codepen visualization to see how things change as I adjust the different values:
We could start by setting a more leisurely rate of change – adjusting the slope (or rate) of growth. To do that, we need to adjust the vw value. At 50vw we would get a font that scales at half the rate of the viewport, but even that seems too dramatic. The default scale from Utopia.fyi uses 0.2273vw for the primary font size. That’s a 1px font-size change for every 440px of viewport resizing! Even the largest font in that scale uses less than a 2vw response rate. Let’s round it off for the sake of our demo:
html { font-size: 0.25vw; }
Now we’re growing at a more reasonable rate, but now our font is way too small. It still starts at 0px for a 0px viewport – and would only be 1px tall on a 400px screen. At that rate, we won’t get to a standard 16px font size until the browser hits 6400px – a very wide screen. This subtle slope only makes sense if we start with an offset. We can do that by adding two values together:
html { font-size: calc(17px + 0.25vw); }
That offset value moves our slope up and down in the visualization, without impacting the slope that we set earlier. Now a 400px browser will give us 18px font-size, and a 1200px browser will result in a 20px font. That’s much more appropriate!
But we still have infinite scaling, and we don’t really need that. We could improve our algorithm even more by providing boundaries with a clamp() function:
html { font-size: clamp(18px, 17px + 0.25vw, 20px); }
That establishes a fixed range for our font-size change, which we can think about in two ways. On the surface we can see the font-size range from 18px to 20px. But when we combine that with the slope and offset, we also have a range of viewport sizes where the font is in transition between those two sizes. In this case, the font begins to grow once the viewport is larger than 400px, and stops growing when we reach 1200px.
As a tool, Utopia starts from these four inputs – min font-size, min viewport, max font-size, and max viewport – and works backwards to determine the proper offset and slope.
Accessibility Issues
I think this is a useful pattern. I like somewhat smaller fonts in tight spaces, and larger fonts when there’s more room. But that comes with caveats – and it’s important for users to get final say with the ability to zoom in or out. If we’re not careful, viewport units and clamp functions can make fonts unable to zoom. I show a few examples of that in my video above, and there are more situations to watch out for, but a simple rule you can follow:
"Addressing Accessibility Concerns With Using Fluid Type
" From Smashing Magazine (smashingmagazine.com)
If the maximum font size is less than or equal to 2.5 times the minimum font size, then the text will always pass WCAG SC 1.4.4, at least on all modern browsers.
Utopia helpfully provides a warning when we create scales that are inaccessible. Maybe I can add that to my demo as well. In the meantime, play with that ‘page zoom’ slider to test different values and see how they interact.