Font size pixels to rems

Beginnings are never easy and setting good foundations for a project is key to avoid headaches down the road.

That’s why the CSS Army decided to use relative units to measure typography (and everything else except from borders) to develop the CSS of the latest version of PatternFly.

Rems

We measure fonts-sizes in rems.

“rem values are relative to the root html element.”

Mozilla Developer Network

For example if the root html is set to 20px, then 1rem = 20 px.

The trick is to avoid hard coding a font-size for the html element. That way 1rem will be equal to the font size base of the browser. In most cases it’s 16px, but users can set it larger or smaller, or browsers can have a larger or smaller root font size according to its environment.

By using rems the typography hierarchy changes proportionally following the browser’s setting.

It sounds awesome, right? Well… there is one challenge.

Photoshop can’t do font-sizes in rems. And when the visual designers delivers a mock up with a font-size in px we need to find a way to express it in rems.

Math and Sass to the rescue

With a little bit of math, the translation from px to rem is easy. First we create a variable to set a value for the root. We don’t apply this value to any element, it works just as a reference point.

Since most browsers font size base is 16px, then the font-size-root variable is 16:

$font-size-root = 16;

Let’s say that the visual designer sets the h1 to 24px. If this equation is true [24 = 24/16 * 16], then this is also true [24 = (24 / $font-size-root) * 1rem] since $font-size-root and 1rem represent the same value. Additionally, since (24 / $font-size-root) yields a numeric value of 1.5 without a unit, multiplying this value by 1rem provides the rem unit, making the final result of this equation 1.5rem.

The sass formula end up been:

(24 / $font-size-root) * 1rem

Putting it all together it looks like this:

$font-size-root: 16;
$h1-font-size: (24 / $font-size-root) * 1rem;

h1 { font-size: $h1-font-size }

It’s like cheating

We are using this technique to set font-sizes, margins and paddings and it has yielded excellent results.

It’s not like cheating, it is cheating. It is also the best way to reproduce Photoshop image in code maintaining the benefits of relative units.

UPDATE 5/15/2017

To make things easier, I wrote a Sass function to translate px to rem:

$font-size-root: 16; // Most browsers font size base is 16

@function px-to-rem($px) {
  @return ($px / $font-size-root) * 1rem;
}

h1 { font-size: px-to-rem(24) }