DEV Community

Cover image for The Battle of the Units: PX vs REM vs EM (font-size)
Ochuko
Ochuko

Posted on • Updated on

The Battle of the Units: PX vs REM vs EM (font-size)

In this article I'm going to go through a few CSS units for customizing the font-size of text when building webpages. There are a lot of other units such as pt, pc, ex, etc. I will be focusing on the 3 most popular units; px, em, and rem.

A lot of developers don't usually understand what the differences between these units are (I didn't either, until much later in my career); so I'm going to try to explain them as clearly as possible.

Let's jump right in! 🚀

PX (pixel)

Pixel is probably the most used unit in CSS and are very popular when it comes to setting the font-size of text on webpages. One pixel (1px) is defined as 1/96th of an inch in print media. On computer screens however, they are not usually related to actual measurements like centimeters and inches like you may think, they are just defined to be small but visible. What is considered visible is dependent on the device.

As we know, different devices have different number of pixels per inch on their screens, this is known as pixel density. If we used the number of physical pixels on the screen of a device to determine the size of content on that device, we would have a problem making things look the same across screens of all sizes. That's where device pixel ratio comes in. It's essentially just a way to calculate how much space a CSS pixel (1px) will take up on the device's screen that will enable it look the same size when compared to another device.

Barney Rubble looking confused

That might have been a lot to take in 😅, let me simplify a bit. Basically, different screens have different number of pixels (pixel density) and computers perform some calculations to ensure consistency in the size of content being displayed on screens, regardless of the pixel density.

I didn't do justice explaining this as this isn't the primary focus of this article but you can check out this video or this article for a more in-depth explanation.

Moving on...

Let's look at an example below.

A dash of HTML:

<div class="container">
  <div>
    <h1>This is a paragraph</h1>
    <p>
      Lorem ipsum, dolor sit amet consectetur adipisicing elit.
      Reprehenderit incidunt perferendis iure veritatis cupiditate delectus
      omnis at! Officiis praesentium officia, nemo veniam consequatur
      nostrum sunt aliquid ipsam, corporis quas quaerat. Lorem ipsum dolor
      sit amet consectetur adipisicing elit. Hic quam beatae voluptatibus
      amet possimus iure impedit assumenda distinctio aliquid debitis, autem
      vel ullam aut, quod corporis ratione atque ducimus dolorum.
    </p>
  </div>
</div>
Enter fullscreen mode Exit fullscreen mode

A sprinkle of CSS:

* {
  font-family: Arial, Helvetica, sans-serif;
}

.container {
  width: 100%;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

.container div {
  max-width: 500px;
  padding: 5px 20px;
  border: 1px grey solid;
  border-radius: 10px;
}

p {
  font-size: 16px;
}

Enter fullscreen mode Exit fullscreen mode

And voila!

Image showing text displayed in different screen sizes

The top box is how it looks when displayed on a larger screen like a laptop, and the bottom box is how it looks when displayed on a smaller screen, like a phone.

Notice how the text in both boxes are of the same in size, That's basically how the pixel works. It helps web content (not just text) look the same size across devices.

You can test it out for yourself on codepen here: https://codepen.io/pedoch/pen/vYjEOzO

EM (M)

The EM unit got its name from the uppercase letter 'M' (em) as most CSS units come from typography. The EM unit uses the current font-size of the parent element as its base. It can essentially be used to scale up or scale down the font-size of an element based on the font-size inherited from the parent.

Let's say we have a parent div that has a font-size of 16px. If we create a paragraph element in that div and give it a font-size of 1em the paragraph font-size will be 16px. However, if we give another paragraph the font-size of 2em that will translate to 32px. Let's take a look at the example below.

A splash of HTML:

<div class="div-one">
  <p class="one-em">1 em based on 10px</p>
  <p class="two-em">2 em based on 10px</p>
</div>
<div class="div-two">
  <p class="one-em">1 em based on 10px</p>
  <p class="two-em">2 em based on 10px</p>
</div>
Enter fullscreen mode Exit fullscreen mode

A drizzle of CSS:

*{
  font-family: Arial, Helvetica, sans-serif;
}

.div-one {
  font-size: 15px;
}

.div-two {
  font-size: 20px;
}

.one-em {
  font-size: 1em;
}

.two-em {
  font-size: 2em;
}
Enter fullscreen mode Exit fullscreen mode

And tada!

Image showing how EM unit works

From the screenshot above we can see how EM can scale up the size of text and how they are affected by the current font-size inherited from their parent container.

You can test it out on codepen here: https://codepen.io/pedoch/pen/ZEoEZMe

Meme saying, "Wait, wait, wait"

Before you get all excited, I must warn you... it's not advisable to use EM especially within complex structured pages. If not used properly, we might run into scaling problems where elements might not be sized properly based on a complex inheritance of sizes in the DOM tree.

REM (Root EM)

Last but not least, REM. This works almost the same as EM, but the main difference is that REM only references the font-size of the root element on the page rather than the parent's font-size.

The root font-size is the default font-size specified either by the user in their browser settings or by you, the developer.

The default font-size of a web browser is usually 16px so therefore 1rem will be 16px and 2rem will be 32px. However, in a case where the root font-size is changed to 10px for example; 1rem will be 10px and 2rem will be 20px.

Let's look at an example to make things a bit clearer.

A pinch of HTML:

<div class="div-one">
  <!-- EM -->
  <p class="one-em">1 em based on container (40px)</p>
  <p class="two-em">2 em based on container (40px)</p>

  <!-- REM -->
  <p class="one-rem">1 rem based on root (16px)</p>
  <p class="two-rem">2 rem based on root (16px)</p>
</div>
Enter fullscreen mode Exit fullscreen mode

A smidgen of CSS:

html {
  font-size: 16px;
}

* {
  font-family: Arial, Helvetica, sans-serif;
}

.div-one {
  font-size: 40px;
}

.one-em {
  font-size: 1em;
}

.two-em {
  font-size: 2em;
}

.one-rem {
  font-size: 1rem;
}

.two-rem {
  font-size: 2rem;
}
Enter fullscreen mode Exit fullscreen mode

And boom!

Image showing how REM unit works compared to EM

As you can see, the paragraphs defined with REM units are completely undisturbed by the font-size declared in our container and are strictly rendered relative to the root font-size defined in the html element selector.

You can test it out on codepen here: https://codepen.io/pedoch/pen/qBYEWjg

The Verdict:

Now that you understand how each unit works, I'll tell you which unit wins this fierce battle for me and why.

As mentioned earlier, I would not recommend you use EM due to the possibility of having a complex hierarchy of nested elements. This can cause problems because EM is relative to the font-size it inherits from its parent, meaning text size can scale uncontrollably if not managed properly.

Bye bye EM👋🏽

woman saying "bye bye"

Now PX and REM basically have the same effect on text; as we would get the same result if we used 32px and 2rem. This is because the default root font-size is 16px.

But REM has an advantage when accessibility comes into the picture.

When considering accessibility, we want users with limited vision to be able to read content on our websites comfortably. One way they can tweak the size of text on the screen is by using the browsers zoom functionality.

GIFS showing browser zoom functionality

The zoom functionality (shown above) works perfectly fine for both PX and REM. However, there's another way this can also be done. This is when the user changes the default font size from the browser's settings. This method allows the text on the user's screen to appear larger or smaller by default based on how they configure it. This frees the users from having to manually zoom every page they visit. Let's see how REM and PX perform with this method.

texts saying "This paragraph is 16px" and "This paragraph is 1rem" styled with 16px and 1rem respectfully

The first paragraph is set to font-size: 16px; while the second is set to font-size: 1rem;. As you can see, they are both the same size.

At the moment, my browser font size setting is on medium. Let's see what happens when I change it to very large.

GIF showing me change browser font size settings from medium to large

The result:

texts saying "This paragraph is 16px" and "This paragraph is 1rem" styled with 16px and 1rem respectfully. But this time the text with REM is slightly bigger because the browser font size setting was changed

As you can see the text set with REM was scaled appropriately with the new default/base font size we specified in the browser settings.

This to me is why I would definitely recommend using REM when working with text content on your web pages.

I think we have a winner!!! 🎉🎉🎉

Girl standing, holding a trophy with confetti rain down on her

Note: REM does have its short comings when dealing with other use cases like padding. I will cover this in a different article.

If you made it this far, I want to say thank you very much.

I haven't written a lot of articles before and I know I have a lot more to learn so if you have contributions or think I didn't get something quite right, please leave a comment; as this will help me to continue to learn and grow.

Once again, thank you for your time and have a lovely day 👋🏽.

Top comments (15)

Collapse
 
divineee profile image
dee-vine

this was genuinely such a fun and insightful read! 😄 thank you for this

Collapse
 
ochukodotspace profile image
Ochuko

Thank you for taking the time out to read it 😄

Collapse
 
wadecodez profile image
Wade Zimmerman

Yeah apparently rem/em should be avoided in spacing because then everything will scale proportionally to the font size which is the same as just zooming in/out.

Collapse
 
christian_legge profile image
Christian Legge

rem won't scale to the font size unless the root font size (and therefore everything on the page) changes, in which case you should treat it as zooming in/out.

Collapse
 
ochukodotspace profile image
Ochuko

Yes, rem wouldn't scale unless the root font size changes

Collapse
 
lico profile image
SeongKuk Han

If I wanna male a responsive website, is 'rem' better in most cases? I'm looking forward to the next post(padding)!

Collapse
 
ochukodotspace profile image
Ochuko • Edited

They are all good with responsiveness as you can use media queries to define the font-sizes at different breakpoints. However, rem gets credit for the way accessibility is handled.

Collapse
 
lico profile image
SeongKuk Han

Thanks for the answer :)

Collapse
 
joelbonetr profile image
JoelBonetR 🥇

It just depends on the use-case at the end 😅

Collapse
 
raguay profile image
Richard Guay

That was one of the best discussions I’ve read on this subject. Thanks.

Collapse
 
ochukodotspace profile image
Ochuko • Edited

I'm happy you enjoyed it 😅

Collapse
 
brianjay profile image
Brian Williams

This was a nice Sunday read 👏🏾

Collapse
 
ochukodotspace profile image
Ochuko

Thanks. I'm glad you enjoyed it 🤲🏾

Collapse
 
ravavyr profile image
Ravavyr

Great write up, but you didn't cover when to use VW for font sizes.
And if you've never used VW for font sizes...well, you haven't lived yet...or gone crazy...

Collapse
 
ochukodotspace profile image
Ochuko

I had no idea veiwport units were used for typography. Defnitely trying this tonight 😂