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. */
And you've got to remember nested elements:
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 ems.

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 the html element.
  • Specify font-size: 1.6em; on the body 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, rems 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 ems 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 rems 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 rems in a host stylesheet.

To use the modified 62.5% font-size trick, simply state the following properties in your stylesheet

  1. font-size: 62.5%; in the :root selector
  2. font-size: 1.6rem in the body 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,

  1. you need a tool,
  2. 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.