Which is Better to Use in CSS: px, em, or rem

First of all, we must understand that there isn’t any best option of measurement unit for all cases, and that’s why this question is mostly opinion-based. But let’s discuss each of the units.

Using px

CSS defines a reference pixel that measures the pixel size on a 96dpi display. On display with a dpi significantly different from 96dpi, the user agent will rescale the px unit so that its size will match the one of a reference pixel.

Pixels are the easiest to use for measurement. However, there is something that we must consider first of all when using it. If you use pixels on your website and there are media queries as well, users will not be able to make the text on your website bigger. So, in this case, it is not good for user experience. Pixels can be good for spacing and layout, but not for font size.

Using em

An em value is equal to the computed font-size of the parent of that element. E. g., if there is a <div> element having font-size: 16px then 1em=16px for the <div> and its child elements. When the font-size isn’t specified explicitly, that element will inherit it from the parent element. This inheritance continues up until the root element. The root element’s font-size is provided by the browser.

Example of using px and em for the font-size:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      .content-container{
        font-size: 20px;
      }
      .content {
        font-size: 1.5em;
      }
    </style>
  </head>
  <body>
    <div id="content-container" class="content-container">
      Parent element
      <div id="outerChild" class="content">
        Outer child element
        <div id="innerChild" class="content">
          Inner child element
        </div>
      </div>
    </div>
  </body>
</html>

Result

Parent element
Outer child element
Inner child element

Here, the computed font-size of the "outerChild" will be 30px (1.5*20px). The "innerChild" uses the font-size from the "outerChild", the already computed font-size of which is 30px. Thus, the computed font-size of the "innerChild" will be 45px (1.5*30px).

When using em for units, be careful with your layout. It’s better not to provide font-size explicitly when using em.

The em unit works well with the layout. Let’s see an example.

Example of using em with the layout:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      .menu {
        font-size: 25px;
      }
      .menu-item {
        font-size: 0.9em;
        padding-left: 12px;
      }
    </style>
  </head>
  <body>
    <div class="menu">
      <div class="menu-item">
        Books
      </div>
      <div class="menu-item">
        Quizzes
        <div class="menu-item">
          Snippets
          <div class="menu-item">HTML Snippets</div>
          <div class="menu-item">CSS Snippets</div>
        </div>
        <div class="menu-item">Tools</div>
      </div>
    </div>
  </body>
</html>

Using rem values

The rem values are relative to the root HTML element. If the root element’s font-size: 16px, 1rem = 16px for all elements. If the font-size isn’t defined explicitly in the root element, 1rem will be equal to the default font-size which is provided by the browser.

Example of using rem for the font-size:

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
    <style>
      :root {
        font-size: 62.5%;
      }
      body {
        margin: 0;
        font-size: 1.6rem;
      }
      .header {
        font-size: 2.4rem;
        padding: 0.8rem;
        background-color: lightgreen;
        text-align: center;
      }
      .flex {
        display: flex;
      }
      .sidebar-left {
        font-size: 1.8rem;
        padding: 0.8rem;
        width: 20vw;
        background-color: pink;
      }
      .content-right {
        padding: 0.8rem;
        background-color: lightblue;
        width: 80vw;
      }
    </style>
  </head>
  <body>
    <div class="main">
      <div class="header">Lorem Ipsum</div>
      <div class="flex">
        <div class="sidebar-left">
          <div>First item</div>
          <div>Second item</div>
          <div>Third item</div>
          <div>Fourth item</div>
        </div>
        <div class="content-right">
          Lorem ipsum dolor sit amet consectetur adipisicing elit. Laborum dolores obcaecati quibusdam hic eos quod, praesentium consectetur reprehenderit facere iusto accusamus fugit quidem suscipit facilis voluptatem fuga maiores quo vel?
        </div>
      </div>
    </div>
  </body>
</html>

Please note that the point of setting the font size of the root element to 62.5% when using rem units is to make it easier to calculate font sizes in rem units. 62.5% of the default font size (which is typically 16px) is 10px. This means that 1rem is equal to 10px, making it easier to calculate font sizes in rem units. For example, if you want to set the font size of an element to 20px, you would use 2rem instead of calculating the pixel value (20/16 = 1.25rem). This can make the code more readable and easier to maintain.

Overall Thoughts:

px (pixel) is an absolute unit and is not scalable. It always stays the same size, regardless of the screen size or the user's preferences. This makes it a good choice for small, fixed-size elements like borders, but it can cause problems with accessibility and responsiveness.

em (em) is a relative unit that is based on the font size of the parent element. It can be useful for creating scalable typography, but it can also be unpredictable when nested inside multiple elements with varying font sizes.

rem (root em) is a relative unit that is based on the font size of the root element (which is typically the html element). Unlike em, it is not affected by the font size of the parent element. This makes it a good choice for creating scalable typography and responsive layouts.

So, which one is better to use? It depends on the specific use case. Here are a few general guidelines:

  • Use px for small, fixed-size elements like borders or shadows.
  • Use em for typography and other scalable elements that need to change size relative to their parent element.
  • Use rem for scalable typography and responsive layouts that need to change size relative to the root element.