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

View More Articles