Flexible type with :root
One element of responsive web design that can be tricky to solve for is typography. Ideally you want to have type that’s as fluid as possible across different viewports. A conventional way of doing this might be to start with a base font size and then change it when you hit a specific breakpoint:
p {
font-size: 1em;
}
@media screen and (max-width: 45em) {
p {
font-size: 1.25em;
}
}
Here the font size doesn’t change until the breakpoint is reached.
Using :root
My preferred approach for more flexible type is to calculate the font size based on the viewport height and width using the :root
selector:
:root {
font-size: calc(1vw + 1vh + .5vmin);
}
Now you can utilize the root em
unit based on the value calculated by :root
:
body {
font: 1rem/1.6 sans-serif;
}
Viewport units
You’ll notice the calc()
function has been passed values in viewport units. Let’s quickly review those to understand how the root font size is being calculated.
1vw
= 1% of viewport width1vh
= 1% of viewport height1vmin
=1vw
or1vh
, whichever is smaller1vmax
=1vw
or1vh
, whichever is larger
If we apply this to the viewport dimensions of the iPhone 7 (current version at the time of this post), which is 375x667, the calculated value of :root
would be:
:root {
font-size: calc(3.75px + 6.67px + 1.875px); /* 1vw + 1vh + .5min */
}
There will always be different approaches to responsive typography, and we should measure each by what we’re trying to solve for, beyond just a responsive state. I’ve found using :root
this way provides the most flexible solution.