Should you use px, em, or rem to size your text in CSS?

NicolasBrondinBernard

Author
@NicolasBrondinBernard

TLDR; The pixel works, but it's better to use rem for accessibility and maintainability.

Article published on 16/03/2021, last updated on 10/08/2026

This article was edited following feedback from a reader, on 03/17/21 at 10:07 PM

For several years now, a debate has been raging in the front-end developer community: "Which size units should be preferred for fonts?"

Many resources on the web go as far as saying that pixels should be completely abandoned, and everything should be replaced with relative units, but then, which unit should you choose?

The pixel is dead, long live the pixel

First of all, one thing needs to be clarified: even relative units like em and rem are directly converted into pixels by the browser, so when we talk about replacing the pixel, it's only when declaring the size in Javascript within the CSS—the browser itself calculates everything in pixels.

Note also that the following information applies to text, but the methodology for sizing other elements doesn't use the same units.

What are the differences?

The px unit

The pixel is the base unit, the one you start seeing as soon as you discover CSS, but you should know that "px" doesn't represent the size of a physical pixel, which is why it's sometimes called a "CSS pixel."

The size of a reference pixel is that of a pixel on a 91dpi screen, and the pixel used in CSS is calculated relative to that size.

Here's an article from Mozilla explaining this concept in detail.

For a retina screen, 4 physical pixels are therefore needed to display a "CSS pixel", which is why media queries for mobile devices are based on sizes below around 500px, even though physical screens have resolutions of several thousand pixels.

So even though we don't consider the pixel to be a "relative" unit, it isn't actually a completely absolute unit either, and it adapts to make life easier for both developers and users.

<style>
  li {
    font-size: 16px; /*Cette taille sera toujours équivalente à 16 CSS pixels */
  }
</style>

The em unit

This unit is relative to the font size of the parent element. Let's say the parent's text size is 16px, then 1em will equal 16px, 2em will equal 32px, and so on...

The problem with this unit lies in nested elements: let's say we set the text size of an <li> element to 1.5em (24px). If we want to create a sublist nested within an existing list item, then the 1.5em of the second-level <li> will equal 36px (1.5*1.5*16).

<style>
  html {
    font-size: 16px;
  }
  li {
    font-size: 1.5em; /* Problème lors d'une imbrication */
  }
</style>

<ul>
  <li>Un élément d'une liste</li> <!-- Taille égale à 24 CSS pixels -->
  <li>
    <ul>
      <li>Un élément d'une sous-liste</li> <!-- Taille égale à 36 CSS pixels -->
    </ul>
  </li>
</ul>

These side effects make the em unit difficult to control and maintain, which is why a new relative unit was created: rem.

The rem (root em) unit

The rem unit works the same way as em, except that it's not relative to the text size of its parent, but to the text size of the root element (hence "root em").

By setting the font size of the <html> document to 12px, the size of a child text set to 2em will equal 24px, no matter where it's placed in the HTML document.

The advantage of rem is that you can change the final size of all your text simply by changing the text size of the root document within media queries.

<style>
  html {
    font-size: 16px;
  }
  
  h1 {
    font-size: 1.5rem; /* Egal à 24px, 21px ou 18px selon la taille de l'écran */
  }
  
  @media (max-width: 800px) {
      html {
        font-size: 14px;
      }
  }
  
  @media (max-width: 500px) {
      html {
        font-size: 12px;
      }
  }
</style>

The rem unit is now supported by 99% of browsers, so you can use it freely.

What's the best solution?

Many years ago, when a user wanted to zoom in on a page, the browser simply enlarged the fonts (without enlarging the elements).

The problem was that text sizes specified in pixels were not affected by zoom, so the solution was to add relative units for font sizes.

Today, modern browsers no longer handle zoom through font sizes—instead, they simply increase the size of the reference pixel, which uniformly increases the size of all elements.

Does that mean I can size my text in px?

In theory, yes, except that for some people with visual impairments, it can be essential to be able to increase only the size of the text, without affecting anything else.

That's why most browsers give users the ability to adjust the default font size (which is set to 16px by default).

So, to allow people with visual impairments to adjust text size uniformly, while also keeping the code maintainable, the ideal approach is to use rem to specify text sizes relative to the default text size defined by the browser (or the user).

I hope this article was useful to you, and see you soon on the blog!


Diana Polekhina sur Unsplash

Finished reading this article?
Our complete courses
Take it to the next level with our courses!

Complete courses, exercises and certificates to really learn programming!

4.8 average rating

Comments (0)

to leave a comment

No comments yet