Rem conversion techniques

Using rem units involves some mental math to calculate their rendered pixel sizes. Let’s explore four techniques to use rem units in CSS with more friendly (read: pixel-like) values.

Preprocessor mixin

  • Ergonomic: No
  • Automatic px fallback: Yes

I frequently see CSS preprocessor mixins used to convert to rem values. I recommend avoiding this technique, as it has two unavoidable issues:

  • Properties must be written using an unergonomic mixin syntax.
  • A complex mixin implementation is needed to convert many valid property values. (I’ve provided very limited functionality in the below example. For a more thorough implementation, see an example mixin.)
@mixin rem($property, $value) {
  #{$property}: $value * 1px;
  #{$property}: $value * 1.6rem;
}
 
p {
  @include rem(font-size, 18);
  font-weight: 400;
}

Preprocessor function

  • Ergonomic: No
  • Automatic px fallback: Yes

Following in the line of using Sass/SCSS, using a simple conversion function trades browser fallbacks for developer ergonomics. The syntax is friendlier than a mixin, which pays off for frequent use, and the following function is just an robust as a substantially more complicated mixin:

@function rem($value) {
  @return $value / 16 * 1rem;
}
 
p {
  font-size: rem(18);
  font-weight: 400;
}

Pixel auto-replacement

  • Ergonomic: Yes
  • Automatic px fallback: Yes

With a slight configuration effort, postcss-pxtorem will convert px units in the input CSS to rem units in the output. The configuration options are robust enough to support any needs I can think of, and if you’re already using PostCSS, there’s no downside to giving it a try.

This tool supports both ergonomic development and older browsers. Bonus points for ease of switching a legacy codebase to rem.

p {
  font-size: 18px;
  font-weight: 400;
}

Pure CSS

  • Ergonomic: Yes
  • Automatic px fallback: No

When you think about the core mathematical goal, perhaps a build tool isn’t necessary. By scaling the root element’s font size, we can make using rem just a friendly as with any tool.

The following example makes for a convenient 1rem to 10px mental conversion:

html {
  font-size: 62.5%;
}
 
p {
  font-size: 1.8rem;
  font-weight: 400;
}
Related articles

Exploring responsive grid systems for complex but structured layouts.

2018
CSS UI patterns
HTML + CSS

Using the flag or media pattern for locking up graphics and text for comments, alerts, and more.

2018
CSS UI patterns
HTML + CSS

A hidden element within a link can stretch the link’s focus outline to the edge of the viewport — and beyond.

2017
Firefox
HTML + CSS