Should I use rem, px, or (gasp!) em? This debate has lots of nuance and I'm not here to choose one for you. I've read a lot of good material on the subject thanks in part to my wondeful coworker Moises Montenegro, including this and also this (both articles favor px). Much of the discussion centers around the nuts and bolts of how the browser interprets each unit, but I'd like to add another dimension to this discussion: that of payload weight.

Note: this article assumes that you are using some sort of CSS preprocessing: perhaps Sass, LESS or Stylus.

A note about CSS weight

When writing preprocessed CSS, consider the output of what you're writing: it's usually quite predictable. For example: deep nesting tends to produce larger CSS files. Consider:

/* style.scss */
$font-size: 16px;

.container {
  .another-container {
    .standard-heading {
      color: #fff;
      font-size: $font-size;
    }
  }
}
/* style.css size: 85B */
.container .another-container .standard-heading {
  color: #fff;
  font-size: 16px;
}

Assuming .standard-heading is used in the same context everywhere on the page, it is better not to nest it so deep. Our file becomes lighter weight and our stylesheet more reusable:

$font-size: 16px;

.standard-heading {
  color: #fff;
  font-size: $font-size;
}
/* style.css size: 55B */
.standard-heading {
  color: #fff;
  font-size: 16px;
}

Of course, saving 30 bytes is nothing to write home about. But keeping these possible savings in mind while writing your application's stylesheets can significantly lighten your CSS payload, keeping page load times down and user experience positive.

Responsive design and media queries

OK, so let's add some design requirements into the mix. What if your requirement is to scale down font sizes when the viewport is narrower than 460px? Here are two approaches:

/* style.scss */

$base-font-size: 16px;
$small-font-size: 14px;
$mobile-width: 460px;

@mixin standard-fonts($size: $base-font-size) {
  p {
    font-size: $size;
  }

  h1 {
    font-size: $size * 3;
  }

  h2 {
    font-size: $size * 2;
  }

  h3 {
    font-size: $size * 1.5;
  }

  footer p {
    font-size: $size * .8;
  }
}

@include standard-fonts();

@media only screen and (max-width: $mobile-width) {
  @include standard-fonts($small-font-size);
}
/* style.css size: 354B */

p {
  font-size: 16px;
}

h1 {
  font-size: 48px;
}

h2 {
  font-size: 32px;
}

h3 {
  font-size: 24px;
}

footer p {
  font-size: 12.8px;
}

@media only screen and (max-width: 460px) {
  p {
    font-size: 14px;
  }
  h1 {
    font-size: 42px;
  }
  h2 {
    font-size: 28px;
  }
  h3 {
    font-size: 21px;
  }
  footer p {
    font-size: 11.2px;
  }
}

This first approach is simple and effective. We have satisfied the requirement and our mobile users are experiencing wonderfully optimized font sizes. We are using px, which is universally supported in all browsers. Why rock the boat? Consider this:

/* style.scss */

$mobile-width: 460px;

html {
  font-size: 16px;

  @media only screen and (max-width: $mobile-width) {
    font-size: 14px;
  }
}

p {
  font-size: 1rem;
}

h1 {
  font-size: 3rem;
}

h2 {
  font-size: 2rem;
}

h3 {
  font-size: 1.5rem;
}

footer p {
  font-size: .8rem;
}
/* style.css size: 251B */
html {
  font-size: 16px;
}

@media only screen and (max-width: 460px) {
  html {
    font-size: 14px;
  }
}

p {
  font-size: 1rem;
}

h1 {
  font-size: 3rem;
}

h2 {
  font-size: 2rem;
}

h3 {
  font-size: 1.5rem;
}

footer p {
  font-size: .8rem;
}

The original example using px totaled 354 bytes of CSS. The rem example totaled 251 bytes of CSS. In this context, rem allowed us a way to scale our fonts in a media query without the use of redundant CSS output. These simple optimizations could mean serious reductions in CSS payload when applied to an entire code base. Of course, if you need to support <=IE8, you're out of luck - rem is IE9 and up.

Rem can help in unexpected ways

Consider the benefits rem can offer your stylesheets, particularly when scaling values. You could potentially shave many kB while writing arguably more elegant CSS.

Tweet your thoughts

How are you using px or rem in your stylesheets? Let me know @jbones3000!