C Tidd

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