engineering

em vs rem in CSS

em vs rem in CSS

Discover the differences between em and rem units in CSS, their benefits in responsive design, accessibility, and when to use each in real-world projects.

Kaushal Joshi

Kaushal Joshi

Dec 03, 2024 11 min read

When I started learning web dev back in 2020, units of measurement in CSS, especially rem and em, confused me a lot. When do you use em over rem? Why do em and rem units exist in CSS, and what design impact do they have? It took me quite a long time to grasp them properly.

In this article, we’ll explore the differences between em and rem. We will see plenty of examples to help you feel confident using these units in your projects. Whether you’re new to CSS or prepping for frontend interviews, you’ll grasp everything you need to know about them by the end of this article.

What are em and rem in CSS?

In CSS, different units help set element dimensions and typography. Absolute units like px represent fixed measurements, which are consistent but lack flexibility in responsive designs.

However, relative units like em and rem adjust with the context, allowing scalability on different screen sizes.

  • The em units base themselves on the parent element’s font size.

  • The rem units refer to the font size defined on the <html> root element.

This flexibility makes em and rem units more versatile for responsive design, as they adapt seamlessly across varying screen sizes.

How em and rem provide flexibility and scalability in responsive design?

Unlike px, which remains static, em and rem dynamically scale based on their respective parent or root font sizes. This adaptability simplifies responsive layouts and enables easy resizing without adjusting individual elements. As a result, designers and developers can maintain a consistent look across different devices, crucial for user experience and accessibility.

Let’s dive deep into each relative unit in the following sections.

The em unit in CSS

The em unit is relative to the font size of the element’s nearest parent. This means that an em value is calculated with respect to the font size of its parent or the current element itself.

This is a simple example that uses em for font size:

<style>
  html {
    font-size: 16px;
  }

  .container {
    font-size: 20px;
  }

  .child {
    font-size: 2em;
  }
</style>

<body>
  <div class="container">
    I am inside the parent container
    <div class="child">I am inside the child container</div>
  </div>
</body>

Let’s break down the snippet:

  • The <html> element, which is the root element of any web page, has a base font size of 16px.

  • The .container class has a font size of 20px.

  • The .child class has a font size of 2em.

Since the .child class is nested inside the .container, its font size is calculated relative to its parent's font size. Therefore, 2em for the .child class results in a font size of 40px (2 * 20px). This demonstrates how em units cascade and compound based on their parent elements.

Most browsers set the default root font size to 16px. Hence, we won’t explicitly mention styling for <html> from now onward.

On the same note, when ever a value is multiplied by 16px, it is being multiplied by the root font size.

Example: Cascading effect with em in CSS

Let’s look at another example to understand em unit. Here is a simple HTML structure that illustrates the cascading behavior:

<style>
  .container {
    font-size: 16px;
    margin: 20px;
  }

  .button {
    font-size: 1.5em; /* Relative to button’s parent font-size */
    padding: 0.5em 1em; /* Scales with font-size */
  }
</style>

<body>
  <div class="container">
    <p>Click the button to <em>submit</em> your form.</p>
    <button class="button">Submit</button>
  </div>
</body>

Let’s break it down and understand what this code does:

  • The <p> tag will have a font size of 16px, as the .container class has a font size of 16px. This would also serve as the base for its child elements.

  • The .button class has a font size of 1.5em, meaning it will scale relative to its parent container’s font size. In this case, the parent container has a font size of 16px. Hence, the button will have a font size of 1.5 * 16px = 24px.

  • The padding property for the button is set in em unit as well. However, this em relates to the font size of the same element. Therefore, the top and bottom padding will be 0.5 * 24px = 12px. Similarly, left and right padding will be 1em, i.e., 24px.

If you play around with the snippet, you’ll get a better idea of how this works.

Example: Compounding effect in em

One of the most important concepts to understand with em unit is its compounding effect. Since it is relative to the font size of the nearest parent, if you use nested elements, their font sizes will multiply based on each parent's font size.

This is quite tricky and one of the most important parts to know while using em units. Let’s understand it better with an example.

<style>
  .parent {
    font-size: 2em;
  }

  .child-level-1 {
    font-size: 1.5em;
  }

  .child-level-2 {
    font-size: 1.2em;
  }
</style>

<body>
  <div class="parent">
    Parent Text
    <div class="child-level-1">
      Child Text - Level 1
      <div class="child-level-2">Child Text - Level 2</div>
    </div>
  </div>
</body>

Now let’s break it down:

  • The font size of .parent class is set to 2em, so its computed font size becomes 2 * 16px = 32px.

  • The font size .child-level-1 class is set to 1.5em. As this class is nested inside .parent class, the value is relative to the .parent div’s font size. In this case, which will be 1.5 * 32px = 48px.

  • The .child-level-2 class is nested inside the div that has class .child-level-1. We just saw that this class has a font size of 48px. Hence, the font size of .child-level-2 will be 1.2 * 48px = 57.6px.

The cascading effect can lead to unintentionally large or small text sizes in nested components, especially if you aren't careful with the em values applied at different levels. This is prone to bugs and unexpected behavior even if you are a skilled developer. Hence it’s extremely important to use it wisely.

The rem unit eliminates the confusing effects of em, and provides a predictable way to set sizing to elements. Let’s learn about the rem unit in the following section.

The rem unit in CSS

rem stands for "root em", and it is relative to the font size of the root element, <html>. By default, most browsers set the root font size to 16px, so 1rem equals 16px unless explicitly changed.

As all units reference the same root font size, it makes it easy to create consistent, scalable designs that can be adjusted by simply changing the font size of the root element.

Let’s look at an example. We’d keep HTML simple

<style>
    .wrapper {
      font-size: 1.25rem
    }

    .nested-wrapper {
        font-size: 2rem;
    }

    .text {
      font-size: 1rem;
    }
</style>

<body>
    <div class="wrapper">
      <p class="text">This text uses rem units</p>
      <div class="nested-wrapper">
          <p id="guess">Guess my font size</p>
          <p class="text">Nested paragraph text</p>
      <div>
    </div>
</body>

In this case, .text will always be 16px, even if it’s deeply nested. Using rem makes it easier to maintain consistent sizes across your app, especially for global styles. However, the <p> tag inside .nested-wrapper will have a font size of 32px. This is because we are not applying the .text class to it, and hence it’d inherit its parent font size. Which is 32px in this case.

Example: rem does not compound like em

Unlike em, rem units do not compound based on parent elements. Because they refer to the root <html> font size, they remain consistent across the document. For example:

html {
  font-size: 16px;
}

.parent {
  font-size: 1.5rem; /* 24px, always 1.5 times the root size */
}

.child {
  font-size: 1rem; /* 16px, still 1 times the root size, no compounding */
}

This ensures predictable scaling for elements throughout a layout, which is especially valuable in global design systems where uniformity matters.

Example: Adjusting font-size property of <html> tag for responsive design

One of the key benefits of rem units is their ability to simplify responsive design. By adjusting the <html> font-size, you can control the overall scaling of elements using rem units. For example:

/* Mobile-first approach */
html {
  font-size: 16px; /* Base font-size for mobile */
}

@media (min-width: 768px) {
  html {
    font-size: 18px; /* Increase base font-size for larger screens */
  }
}

.container {
  padding: 2rem; /* Adjusts according to the <html> font-size */
}

When the <html> font size is modified, all elements sized with rem units adjust proportionally, making it simpler to build responsive designs without manually recalculating individual sizes.

Hence, the .container class will have 32px padding on smaller devices, and 36px on devices with screens larger than 768px.

Accessibility Benefits of rem Units

Using rem units can enhance accessibility. By modifying the root font size, text and layout elements can adapt uniformly, improving readability across the page. For instance, users with low vision can scale the text through browser settings or CSS variables, as changes at the root level cascade predictably.

This approach also aligns with best practices in inclusive design, allowing content to remain readable without disrupting the layout.

When to Use em vs. rem

Choosing between em and rem depends on the specific use case:

  1. Use em for component-specific scaling: If you have a button or a card component that should scale based on the parent element’s size, em can be a good choice.

  2. Use rem for global consistency: For base font sizes, margins, padding, or any layout-related styling, rem keeps everything consistent, regardless of the component hierarchy.

Let’s look at an example that combines both em and rem in a button component.

Real-World Use Case of em and rem in CSS

Now that we are clear on what em and rem in CSS, what are their differences, and when to use which unit, let’s build a simple card component to completely grasp the ideas.

We’d keep the HTML structure very short and simple:

<style>
  .card {
    font-size: 1rem; /* Base font size for card is 16px */
    padding: 1.5rem; /* 1.5 * 16px = 24px */
    background-color: #f4f4f9;
    width: 16rem; /* 16 * 16px = 256px */
    border-radius: 0.5rem; /* 0.5 * 16px = 8px */
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  }

  .card-title {
    font-size: 1.5em; /* 1.5 * 16px = 24px, based on card's font size */
    margin-bottom: 0.5em; /* Scales with the title font size */
  }

  .card-desc {
    font-size: 1em; /* 1 * 16px = 16px */
    margin-bottom: 1rem; /* 1 * 16px = 16px, using root font size */
  }

  .card-btn {
    font-size: 1rem; /* 1 * 16px = 16px */
    padding: 0.5em 1em; /* Padding scales with button font size */
    color: white;
    background-color: #3498db;
    border: none;
    border-radius: 0.25em; /* Scales with button size */
  }
</style>

<body>
  <div class="card">
    <h2 class="card-title">Card Title</h2>
    <p class="card-desc">This is a description of the card.</p>
    <button class="card-btn">Read More</button>
  </div>
</body>


This might feel complicated at first glance. So, let’s break it down:

  • The .card uses rem for width, padding, and border radius, ensuring consistent spacing based on the root font size.

  • .card-title uses em for font size, scaling relative to the .card's font size (24px).

  • .card-desc also uses em for font size, remaining at the base size of .card (16px), with rem for margin.

  • The .card-btn uses rem for font size and em for padding, keeping button size flexible relative to text size.

This is how it’ll look in the browser.

Interview Preparation

If you are preparing for frontend developer interviews as a junior developer, you will most likely get asked about rem and em during interviews. I hope by reading this blog, you have a solid idea about both. Before we end, here are some interview questions regarding what we covered in today’s article:

  1. What are absolute units in CSS? What is the difference between em and rem units?

  2. How does em work in relation to its parent element's font size?

  3. What does it mean when we say em units are relative?

  4. What does rem stand for, and how is it different from em?

  5. Can you explain a scenario where using em might be more beneficial than rem?

  6. How do em and rem units respond when the root font size changes in a media query?

  7. What is the compounding effect in em units, and why is it important to be aware of it?

  8. Write a code example showing how em units work within nested elements and how their font sizes multiply.

  9. If a button is styled with font-size: 1.5em and padding: 0.5em 1em, how do these values scale relative to its parent container’s font size?

  10. In the following scenario, what would be the font size of .child relative to .container?

    .container {
      font-size: 20px;
    }
    .child {
      font-size: 2em;
    }
    

If you were able to answer at least 8 out of these 10 questions, congratulations! You’ve fully understood em and rem units in CSS. Read this article again to revise before you go for the interview.

Wrapping up

In this article, we learned about rem and em units in CSS. We covered what rem and em are, what are they used for, and what are the differences between them, and also saw a bunch of examples to understand them better. We finished with some interview questions for you to prepare.

I hope you learned something valuable after reading this article. If you did, feel free to share it with your friends and peers so they learn about this too.

If you are looking for a new job or want to share a cool project you built with like-minded folks, consider Peerlist! It’s a professional network to show and tell what you’re working on!

Until then, happy coding! 👨‍💻

Create Profile

or continue with email

By clicking "Create Profile“ you agree to our Code of Conduct, Terms of Service and Privacy Policy.