As you can see, 1rem would always take on the value of 16px no matter where you set it (unless you changed the font-size of <html>).

It’s dependable. It’s simple to understand.

That’s rem. Pretty easy to get once you know what em is, don’t you agree?

Now, let’s get into the meat of this article. rem or em?

REMs or EMs?

It’s highly debatable.

Some developers avoid rem entirely, claiming that using rem make their components less modular. Others use rem for everything, preferring the simplicity that rem provides.

Oddly, I fell into the trap of strictly only rem or em at different points in my development career. I loved how em helped me make modular components, but I loathed the complexity it brought to my code. I also loved how rem made calculations simple, but I hated the hacks I used to make my components modular.

Turns out, rem and em have their strengths and weaknesses. They should be used differently, depending on the circumstances.

How? I have two simple rules:

Size in em if the property scales according to it’s font-size

Size everything else in rem.

A tad too simple? Well, let’s consider writing a simple component (a header element) either using rem or em, and you’ll see how these two rules play out nicely.

Using Only REMs to Make a Header Element

Say you have a header element (<h2>) that looks like this:

I’m a header!

The header’s styles should be similar to the following if you sized everything in rem:

Notice the pattern here? .header--large‘s font-size is twice as large as .header. Consequently, padding on .header--large is twice as large as the padding on .header.

What would happen if we have more headers of different sizes, or if the headers have to change in size? You can already see how coding the entire site in rem can cause duplication and super complex code.

We can simplify the code such that there’s no need to redeclare padding on .header--large if we don’t mind using both em and rem:

Notice the pattern here? The font-size of .header--large is twice the size of the font-size of .header. Yet, the padding-left and padding-right of .header--large are half the padding-left and padding-right of .header!

Like in the above case, we can simplify the code if you are open to using a combination of rem and em in your code. Specifically, rem for left and right paddings and em for top and bottom paddings:

Unfortunately, this doesn’t turn out well. The margin between small component A and small component B is larger than the gutter width at a viewport above 800px.

Space between the two smaller components isn’t equal to the gutters when the screen is wider than 800px

Boo :(

This happens because the font-size of the component is 1.5em (or 24px) when the viewport is larger than 800px. Since the font-size is 24px, the computed value of 2em becomes 48px, which is different from the 32px we were looking for.

Grrrrr! (╯°□°）╯︵ ┻━┻

Thankfully, we can solve this issue simply by sizing in rem since we know we’re the gutter width is sized according to the root font-size.

Note: You need to use Flexbox to build this grid. I won’t explain how I built it since it’s way out of scope. Check out this article if you’re interested in finding out more about Flexbox

Oh by the way, I didn’t come up with this technique. Chris Coyier wrote about it a year ago. (He’s a genius).

Anyway, are we good so far? If yes, let’s move on to case 2. If not, feel free to leave a comment and I’ll figure a way to explain this further.

Case 2: Properties of Some Elements Scale With The Component’s Font-Size

Case 1 is easy to understand. The downsides though, is that it’s tough for you to stay true to your modular scale, main good vertical rhythms and ensure that every component is sized well AT the same time (especially when building responsive websites).

Sometimes you just need to tune a small section of your component instead of resizing everything at once. For example, you might want to change only the header font-size at a larger viewport.

Only the headers change in size when the viewport changes

Let’s start styling this case by taking a look at the basic styles we wrote above:

Tada! Notice how only the header font-size changes as we resize the browser now? That’s how you build for case 2 :)

One more thing.

Since it’s a best practice to use only a handful of typography sizes, I often find abstract the font-size property away from the component. This way, it becomes easy to ensure that your typography remains consistent across all components.

Here’s a question you’ll probably ask, so I thought I’ll answer it first: Which method should you use?

I’ll say it depends on your design.

Personally, I find myself working with Case 2 more often than Case 1 since I prefer abstracting away typography into a file of it’s own.

Wrapping Up

So, should you use rem or em? I think that’s not the right question to ask. Both rem and em has their strengths and weaknesses, and they can be used together to help you make simple, modular components!

On to you now! What’s your take on this debate? I’d love to hear what you think in the comments below! :)

(If you liked this article, I'd appreciate it if you could share it. 🤗)