Font Size Idea: px at the Root, rem for Components, em for Text Elements

Avatar of Chris Coyier
Chris Coyier on (Updated on )

Me, for the last year or so: “rem‘s are so cool! I’m gonna size everything with them, that way I can adjust the font-size on the root element and everything will scale with it!” It was a nice dream. And it wasn’t a disaster. That’s what I’m doing right now here on CSS-Tricks and this is how it plays out in a very simple scenario:

That comes from essentially:

/* Document level adjustments */
html {
  font-size: 17px;
}
@media (max-width: 900px) {
  html { font-size: 15px; }
}
@media (max-width: 400px) {
  html { font-size: 13px; }
}

/* Type will scale with document */
h1 {
  font-size: 3rem;
}
h2 {
  font-size: 2.5rem;
}
h3 {
  font-size: 2rem;
}

I admit that I like that simplicity, but I’m starting to think it’s a little too dreamy for all but the simplest of sites. The main issue: you just can’t expect type that you set at one screen size to look just right by simply scaling it down entirely proportionally. Big type might get too big scaling up. Small type might get too small (a common one that gets me). Or even the reverse of either, where big type might not get small enough.

If any of those things happen, then you’re making @media query specific adjustments which not only gets confusing but isn’t very efficient (adjusting size just to adjust it again to fix it).

So here’s my idea: you still keep px size adjustments at the document level so you can make easy/efficient sweeping size changes. But then each module on the page has a font-size set in rem. Actual text elements (h1, h2, p, li, whatever), if you size them at all, are sized in em, and thus become relative to the module.

This way you can adjust font-size at a module level, which is pretty easy. The chances the type within a single module have good proportions and can scale together nicely is high. So that would play out like this:

Not to scale. Just showing what units would go on what.

You can play around with the idea here by adjusting the sliders:

See the Pen Em AND Rem by Chris Coyier (@chriscoyier) on CodePen.

At a certain medium size, everything looks fine. Scaling up, you can get to a point where the main articles are a good big size, but the sidebar stuff doesn’t need to be that big. With this system it would be easy to target them and notch them back down. Scaling down, those sidebar modules get a bit too small too fast, so you could notch them back up easily. There might even be sizes where you equalize things because you’ve gone single column (or the like).

This is how it would go down:

/* Document level adjustments */
html {
  font-size: 17px;
}
@media (max-width: 900px) {
  html { font-size: 15px; }
}
@media (max-width: 400px) {
  html { font-size: 13px; }
}

/* Modules will scale with document */
.header {
  font-size: 1.5rem;
}
.footer {
  font-size: 0.75rem;
}
.sidebar {
  font-size: 0.85rem;
}

/* Type will scale with modules */
h1 {
  font-size: 3em;
}
h2 {
  font-size: 2.5em;
}
h3 {
  font-size: 2em;
}

I put “idea” in the title because I haven’t actually built a site doing this yet, but it makes sense to me and I’d surely try it.