The 62.5% font-size trick (+Infographic)
Many a time, we use tools to convert px
to a relative unit such as em
or rem
. Yet, we get weird-looking decimals like 0.9375rem. Problem is, afterward, it's hard to know if 0.9375rem is 13px, 14px, or something else.
The 62.5% font-size trick helps us use a pixel value along with a relative unit. This way, we do without conversion tools and still have better readable values.
As introduced by Richard Rutter in 2004, you only have to include the style font-size: 62.5%;
on the body element. Now, you can specify 1.7em instead of 1.0625em for 17px, 1.8em instead of 1.125em for 18px, and so on.
Useful technique right?
Well, some think it's pointless, archaic, and breaks expectations. As such, it shouldn't be recommended. In fact, Richard Rutter who introduced it recommends something else now. So, case closed? Not so fast.
No doubt, some of these are valid reasons at some point. Good thing is, we were mistaken. It turned out that the problem isn't the technique but something else. This post takes you through time to understand the misconceptions.
Let's start with the essence of converting px
to em
or rem
and still think in px
.
Why think in pixel (px)?
The lifecycle of a web design project starts and ends with px for measurement. UI Designers design in px, and Browsers paint in px.
Thinking in pixels makes it easy to do the following:
- Translate UI Design to code.
- Read the code in the editor.
- Troubleshoot the code in the browser.
This ensures a better development experience. In addition, the mental model is maintained across the team.
Why convert px to em or rem?
If it's okay to let users decide at what font size it's best for them to read a webpage, we need to use font-relative units.
Of course, with px, users can enlarge text by zooming in or out. Yet, changing the browser's font size helps them set it once and avoid zooming each time they visit a webpage.
Converting px
to em
or rem
makes the element responsive to the user's preference.
Reasons said, we shall now evaluate the 62.5% trick by its compatibility with em
and rem
of both author and 3rd party stylesheets.
Compatibility with em units of Author Stylesheet
Back in 2004, browsers supportted em
units, not rem
. By design, em
compounds as it can relate to the parent's font size. Of which the parent, if uses em, relates to its own parent. And it goes up to the user's preference in the browser settings.
Because em compounds, the 62.5% trick is only useful for top-level ems. And this is totally fine!
Compatibility with em units of 3rd Party stylesheet
Recall the trick's style of font-size: 62.5%
on the body element? This will compute to 10px if the user's preference is 16px (a default in the browser's settings).
This is no problem for the author's stylesheet. Since the expectation of 16px is met with 1.6em as per the trick. Nor is it an accessibility concern because 62.5% is relative to the user's preference.
However, a computed value of 10px is no expectation for 3rd party stylesheets like that of the browser.
Moreover, it becomes easy for the user's minimum font size to kick in if declared. (Mozilla Firefox used to have a value of 12px but not anymore.)
Anyways, we can resolve both issues with a reset. In any of the following 2 methods.
Reset Method 1
We can reset on each HTML element. It'd look like this
h1 {
font-size: 3.2em;
}
/* h2, h3, h4, etc. */
p, li, /* etc. */ {
font-size: 1.6em;
}
/* etc. */
li li /* , etc. */ {
font-size: 1em;
}
/* etc. */
If you intend to leverage the browser's style, this method won't help. For components where you'll need custom styles, this method becomes useful for top-level em
s.
Reset Method 2
An easier way to reset the 62.5% trick for compatibility with em-based 3rd party stylesheets is to do the following.
- Move the style
font-size: 62.5%;
to thehtml
element. - Specify
font-size: 1.6em;
on thebody
element.
Now, we are back to square-one! Here's why:
- we've used the trick's one-time benefit on the body element.
- the current state is as good as not specifying the trick
So, if anyone says it's pointless, that's a reason!
But, there's still a use-case.
Compatibility with rem units of Author's Stylesheet
Around 2014, a decade after this trick was introduced, rem gained most browser support. Unlike em
, rem
s don't compound as they relate to the root's font size.
Hence, the 62.5% trick becomes useful for all occurrences of rem in the author's stylesheet.
Hold on, spoiler ahead:
Compatibility with rem units of 3rd party stylesheets
The wave of rem's simplicity blew across the ecosystem. For example, Bootstrap, a 3rd party stylesheet, also adopts rem for version 4. Let's skip the semantics of em
vs rem
for now.
Because the computed root's font-size is 10px, the 62.5% trick becomes useless for all occurrences of rem
in a 3rd party stylesheet.
At this point, you may give up on the trick because it only supports top-level em
s and author's rem
. Leaving out 3rd party stylesheets that use rem
.
But, I implore you to take a step back and consider if it's semantic to use rem
units in a 3rd party stylesheet.
Should 3rd party CSS use rem?
Let's examine this via the user of a 3rd party CSS, which we shall refer to as the Client.
It's fair to say: a client should be able to use 1 or more 3rd party stylesheets. Each on different components of a page.
And if the client wishes, they may font-scale a component independent of another.
Unfortunately, 3rd party CSS with rem
units will have values tightly coupled to the client's global font size. Hence, they won't be responsive to a local font size.
This becomes a problem when a client needs to scale a component by its local
font size. A problem 3rd-party CSS authors can avoid if they use em
.
Clearly, this is a case of em
vs rem
.
Picking on Richard Rutter's guide for setting font-size of an element in 2016, he said: use rems for global sizing, use ems for local sizing
.
Earlier in 2014, Chris Coyier puts it explicitly in the font sizing idea:
Actual text elements (h1, h2, p, li, whatever), if you size them at all, are sized in em, and thus become relative to the module. This way, you can adjust font-size at a module level.
Thus, since 3rd party stylesheets are meant to be distributable, it makes sense that they can adapt locally to wherever they find themselves. Using em
, rather than rem
, in 3rd party CSS makes them more universal and responsive.
That said, there might be a case scenario where a 3rd-party CSS author wouldn't want an element to scale via a component it find itself. Neither can they afford to use an absolute unit.
At that moment, rem
fits the scenario. Only that, a change in the client's root font size affect components of other 3rd party CSS.
What to do?
With CSS Variables, 3rd-party CSS can make global rem
s local to their own stylesheet. Implement looks like this:
:root {
/* provides a factor clients can use to scale
`rem` units of a particular CSS package. */
--packageFooRemFactor: 1;
/* provides a convience function to create
rem units local to this CSS package */
--localRem: calc(--var(--rem) * var(--packageAFontFactor) * 1rem);
}
/* Specify rem units local to this package */
.example {
--rem: 1;
font-size: var(--localRem);
}
This means, 3rd-party CSS should use
em
for scope-able relative values- local
rem
for non-scope-able relative values
Summary
Using appropriate units in a 3rd-party stylesheet ensures the modified 62.5% trick is useful for all occurences of rem
s in a host stylesheet.
To use the modified 62.5% font-size trick, simply state the following properties in your stylesheet
font-size: 62.5%;
in the:root
selectorfont-size: 1.6rem
in thebody
selector
Here's the code:
:root {
font-size: 62.5%;
}
body {
font-size: 1.6rem;
}
Concerns
There are a number of concerns around the 62.5% technique. Below are some and my humble opinions.
It breaks 3rd party stylesheet
Ironically, this is good as it forces library authors to adopt em
. This in turn, give developers more flexibility.
It may render smaller when users use the minimum font size (MFS) setting
With or without the technique this effect will kick in if the computed font size is less than the MFS.
Despite that, there's no cause for alarm. Because, the modified trick decreases the font size on the :root
and resets it on the body
. Hence, elements within the body
gets their expected value.
It ruins user preference or accessibility
Big NO. The trick uses a %
unit which is relative to the user's preference in the browser settings.
You can't integrate it into a stylesheet that doesn't use the technique
That's true until we've a tool that convert rem values of 62.5% to 100%.
No point. It's not necessary
This opinion tends to be true if you use the reset method 1. By the way, you should use the modified 62.5% trick.
Alternatives
if you're locked-in on a 3rd party CSS that uses rem
, consider the following alternatives to the 62.5% trick.
Each of these alternatives is evaluated based on the readability in both the source code and the DOM.
CSS Calc
calc can be used to convert px to em/rem on the go. But, it isn't as simple to read or write like the 62.5% trick.
In the code below, 18rem will be read as 18px both in the source code and the DOM.
.component {
font-size: calc(18rem / 16);
}
Below is another variant. It's more verbose than the previous.
Here, we can easily read the value of the --px
variable.
:root {
--pxToRem: calc(var(--px) / 1rem);
}
.component {
--px: 16;
font-size: var(--pxToRem);
}
Preprocessor functions
Functions from CSS preprocessor are easy to read in source code but not in the DOM
In the code below, we'll read it as 15px. But in the DOM, it'll be 0.9375rem.
/* pxToRem() is a preprocessor function */
.component {
font-size: pxToRem(15px);
}
Generators
You can use a tool to precompile values. And leverage on CSS variables for better readability.
/* step 1: declare variable from generators */
:root {
--14px: 0.875rem;
--16px: 1rem;
--18px: 1.125rem;
--20px: 1.25rem;
/* ... */
}
/* step 2: use declared variable */
.component {
font-size: var(--14px);
}
The downsides to this approach are,
- you need a tool,
- you can get an overwhelming list of values. Especially, when it comes to minutiaes like spacing which are highly dependent on visual perceptions.
Verdict
The 62.5% font-size trick is still relevant today! Even among the alternatives. The only challenge is getting 3rd party CSS to use appropriate units. Units tailored to how its user may use the package.
So, are you convinced already? Will you be using the 62.5% trick anytime soon? or You've damned it? Let's discuss on Twitter.
Infographic
By the way, there's an infographic I made to summarise the 62.5% font-size trick in one shot. You can download the infographic for free and get design updates if any come up.