Home » How To » What Are CSS Units For Font-Size: Px | Em | Rem

What Are CSS Units For Font-Size: Px | Em | Rem

When I started digging into CSS, I found various units for font-size. It was a bit confusing as to which one to use when, where and why. After investing some time, I found three units that I decided to use in my projects – pxem and rem.

px

Pixels are the easiest measurement to use. But there is a catch. Let’s say we used pixels throughout our website and we managed the media queries too. What if a user changes the default font-size of browser (or device)? Your header’s font-size (say 20px) will remain 20 px. Hence user’s font preferences won’t be reflected. Which is not a good user experience. So, pixels may be good at spacing and layout but are not good fit for font-size. ems and rems are at rescue.

em

An em is equal to the computed font-size of that element’s parent. For example, If there is a div element defined with font-size: 16px then for that div and for its children 1em = 16px.

If font-size is not defined explicitly, that element will inherit it from the parent element. The inheritance continues to take place this way amongst ancestors up until the root element. Default font-size of the root element is provided by browser.

Here is an example for em.

<div id="parent" class="parent">
  Parent
    <div id="outerChild" class="child">
      Outer child
      <div id="innerChild" class="child">
        Inner child
      </div>
    </div>
</div>
.parent {
  font-size: 20px;
}
.child {
  font-size: 1.5em;
}

Here, you can see we gave font-size: 20px to.parent and font-size: 1.5em to.child. Computed font sizes of both .child(#outerChild and #innerChild) are different. #outerChild uses font-size from its parent .parent. So, computed font-size of #outerChild will be 1.5 * 20px = 30px. And #innerChild uses font-size from its parent #outerChild (which already has computed font-size of 30px). Hence the computed font-size of nested .child will be 1.5 * 30px = 45px.

If you want to use em for your units, you have to be careful with your layout. It is a good practice not to define font-size explicitly except root element while using em in your project.

em works great with layout like sidebar menu where you want submenu items to have smaller font-size gradually. Here is an example for that.

Result Skip Results Iframe
EDIT ON
<div class="menu">
  <div class="menu-item">
    Home
  </div>
  <div class="menu-item">
    About
    <div class="menu-item">
      Projects
      <div class="menu-item">Professional Projects</div>
      <div class="menu-item">Hobby Projects</div>
    </div>
    <div class="menu-item">Portfolio</div>
  </div>
  <div class="menu-item">
    Services
  </div>
  <div class="menu-item">
    Contact
  </div>
</div>
/* Parent */
.menu {
  font-size: 25px;
}

/* Child */
.menu-item {
  font-size: 0.9em;
  padding-left: 12px;
}

rem

rem values are relative to the root html element, not to the parent element. That is, If font-size of the root element is 16px then 1 rem = 16px for all elements. If font-size is not explicitly defined in root element then 1rem will be equal to the default font-size provided by the browser (usually 16px).

When it comes to spacing and font-sizing, I prefer to use rem. Since rem uses root element’s font-size instead of its parent’s font-size.

Let’s assume, font-size: 10px is set for the root element which makes 1rem = 10px everywhere in our webpage. Since 1px = 0.1rem, calculations are easy. But setting root font-size in pixels will have same problem as I mentioned in the px section.

A solution for this problem is percentage. Usually default font-size of the browser is 16px. Setting font-size: 100% will make 1rem = 16px. But it will make calculations a little difficult. A better way is to set font-size: 62.5%. Because 62.5% of 16px is 10px. Which makes 1rem = 10px.

Here is an example code in SCSS:

<div class="main">
  <div class="app-header">Header</div>
  <div class="app">
    <div class="sidebar-menu">
      <div>Menu item 1</div>
      <div>Menu item 2</div>
      <div>Menu item 3</div>
      <div>Menu item 4</div>
    </div>
    <div class="content">
      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>
:root {
  font-size: 62.5%;
  body {
    margin: 0;
    // Body font size 16px
    font-size: 1.6rem;
  }
}

.main {
  .app-header {
    // Header font size 24px
    font-size: 2.4rem;
    // Header padding 8px
    padding: 0.8rem;
    background-color: lightblue;
    text-align: center;
  }
  .app {
    display: flex;
    .sidebar-menu {
      // Menu font-size 18px
      font-size: 1.8rem;
      // Menu padding 8px
      padding: 0.8rem;
      width: 20vw;
      background-color: lightgreen;
    }
    .content {
      // Content padding 8px
      padding: 0.8rem;
      background-color: pink;
      width: 80vw;
    }
  }
}

article-wrap

ems and rems solved problems which I faced using pixels. I use rem in spacing (margin, padding, etc.) and font sizing. And I use em for layouts like menu.

Photo of author

Saksham Bhargava

Saksham is a tech enthusiast who loves talking about new gadgets and innovations. He loves travelling, particularly to places not frequented by tourists. In his free time, you will find Saksham beating the phone at PUBG Mobile or streaming new highly-rated TV series.