A strange Chrome bug with body font-size in rem

Updated 2016-03-13

This is documented elsewhere but since I just encountered this bug and it baffled me, I’m still writing about it. Chrome (up to Chrome 33 at least) seems unable to compute the correct font-size on the <body> element when you use the rem unit. I reported the bug here, since I didn’t find a previous report.

In other words, avoid this: body { font-size: 1.2rem }

But use this for the same effect: body { font-size: 120% }

March 2016 update: looks like this bug has been fixed for a handful of Chrome versions already.

Why would one use rem on body?

A common pattern is to define a percentage base font-size on the root element, and to use the rem unit in your CSS to reference that value. Some people use a percentage value such as:

html {
  font-size: 62.5%; /* Generally results in 1rem -> 10px */

If you want to work with a base font-size of say 15px, you might also declare that pixel value rather than a percentage value, and then use the rem unit in your CSS in order for some dimensions, margins and whatnot.

Me, I tend to use font-size: 125% on the root element, which generally results in a nice round 20 pixel layout unit. I like going bigger than the default 16px, rather than smaller.

What happens in Chrome

When you use rem to define the font size on the <body> element, it might not be computed on page load. Here is a test page illustrating that (load it with Chrome and any other browser, and compare; both paragraphs should have the same font size).

On this website, Chrome would get the body’s computed font-size right roughly one in three page loads. It seems that some layout reflows might trigger Chrome to compute the body’s font-size again, which then fixes the issue. But of course we want to get the right rendering on the first rendering. Here’s what it looked like:

First page load on the left, after reload or reflow on the right

Simple fix

Don’t use the rem unit to define font-size on the <body> element.

Note that it’s still okay to:

A simple workaround if you do want to define a base font-size for the document that is different from the root element’s computed font-size (aka rem), would be to use percentages here as well.

Let’s wrap up with an example:

/* Root font-size (defines the value of 1rem) */
html { font-size: 125%;   /* -> 20px */ }

/* Base font-size (defines the default text size,
   if different from 100%/1em/1rem) */
body { font-size: 75%;    /* -> 15px */ }

/ * Usage */
h1   { font-size: 2rem;   /* -> 40px */ }
h2   { font-size: 1.5rem; /* -> 30px */ }
h3   { font-size: 1rem;   /* -> 20px */ }
p    { /* no font-size */ /* -> 15px */ }

Our last test page (4) verifies that this works in Chrome.