em vs rem - Most confusing CSS units explained
Tags: webdev, beginners, css, frontend
Published: 2022-05-01 10:31:20

_em_ and _rem_ are two of the most commonly used CSS relative units. They are also one of the most common sources of confusion among beginners. In this article, we'll see what exactly they are and how to use them.

<u>**Relative Units**</u>

Relative units derive their sizes from other properties. Unlike absolute units(like pixels, inches etc.) whose sizes are independent of other units, the sizes of relative units change according to that of other properties.

In particular, _em_ and _rem_ are relative to the font sizes of parent and root elements respectively. Let's understand with this an example.


<u>**em vs rem**</u>

First, we'll define two containers, one each for _em_ and _rem_ respectively.

```
<div class="em-parent">
  <p>em-size</p>
</div>

<div class="rem-parent">
  <p>rem-size</p>
</div>
```

Now, let us set the font-sizes for the root element and the children of _em-parent_ and _rem-parent_ containers.

```
:root {
  font-size: 32px;
}

.em-parent p {
  font-size: 1em;
}

.rem-parent p {
  font-size: 1rem;
}
```

As we can see from the result below, both the child elements derive their sizes from root element (_1em = 1rem = 32px_).

{% codepen https://codepen.io/valeshgopal/pen/oNpVWxJ %}

Now let's see what happens to the font-sizes of the child elements when we set the font-sizes of their parent containers.

```
:root {
  font-size: 32px;
}

.em-parent {
  font-size: 64px;
}

.em-parent p {
  font-size: 1em;
}

.rem-parent {
  font-size: 64px;
}

.rem-parent p {
  font-size: 1rem;
}
```

{% codepen https://codepen.io/valeshgopal/pen/JjpjJBp %}
As we can see from the result, the _em_ unit is deriving its size from its parent container, whereas the _rem_ unit remains fixed to the font-size of the root element, unaffected by the font-size of its parent container. So in this case, _1em_ becomes _64px_ and _1rem_ remains _32px_;

So remember, _em_ derives its size from its parent, and in the absence of the parent's font-size, it derives its size from the root element. Whereas _rem_ always remains fixed to the font-size of the root element. 

Now that we understand the basic difference between _em_ and _rem_, let's get into their application.


<u>**How to use _em_ and _rem_**</u>
_em_ and _rem_ are most commonly used to set font-size, padding and margin of the elements. But another difference between _em_ and _rem_ is that, _em_ has a compounding effect on padding and margin, whereas _rem_ always remains constant. That may sound confusing. So, let's understand it with an example.

We'll use two buttons to demonstrate this example.

```
<div class="button-1">
  <button>button 1</button>
</div>

<div class="button-2">
  <button>button 2</button>
</div>

```

Now let's set the properties of both the buttons in _em_.

```
:root {
  font-size: 16px;
}

.button-1 {
  font-size: 16px;
}

.button-1 button {
  font-size: 1em;
  padding: 1em;
  margin: 1em;
}

.button-2 {
  font-size: 16px;
}

.button-2 button {
  font-size: 1em;
  padding: 1em;
  margin: 1em;
}
```

{%codepen https://codepen.io/valeshgopal/pen/ZErEJzy %}

Let's increase the font-size of button 1 to _2em_(2 * 16 = _32px_) and see what happens.

```
.button-1 button {
  font-size: 2em;
  padding: 1em;
  margin: 1em;
}
```

{%codepen https://codepen.io/valeshgopal/pen/poaorXV %}

Apart from increase in its font-size, something interesting has just happened in _button 1_. Can you notice it? No? It might be a bit difficult to notice with naked eye. So, let me show what happened. 

![button 1 illustration](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0u7v6rvw3aio8hvkhqy8.jpg)

Notice that the padding and margin of _button 1_ have also increased to _32px(2em)_ even though they are set to _1em_. This is because of the compounding effect of _em_. While the _em_ of child derives its size from its parent, the _em_ of padding and margin of the child are derived from its own font-size. 

So in this example, 
_1em_ of child element = font-size of parent container = _16px_; 
_1em_ of padding/margin = font-size of the element = _2em_ = _32px_;

![em vs rem difference](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t8636700hcu2ar05v4dm.jpg)

Now, let's also increase the font-size of _button 2_ to _2em_ and set the padding and margin to _1rem_ each. This will help us visually understand the difference between _em_ and _rem_ better.

{%codepen https://codepen.io/valeshgopal/pen/ZErEXLP %} 
The padding and margin in _button 2_ have remained _16px_ each. Ideally, we would always want the padding of an element to remain proportionate to its font-size. Notice in the above example, the _button 2_ looks congested when we increase its font size, but keep its padding fixed to _1rem_.
 
So, it is a good practice to always set the padding of elements in _em_ like we did in _button 1_.

And as we increase or decrease the font-sizes of the elements, we would want the spacing between them to remain constant. That is why it is a good practice to set the margin in _rem_. Let's make the change in our code and see the difference. 

```
.button-1 button {
  font-size: 2em;
  padding: 1em;
  margin: 1rem;
}

.button-2 button {
  font-size: 2em;
  padding: 1em;
  margin: 1rem;
}
```

![em vs rem margin](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w16abvq650k5enf4k88d.jpg)

Notice that if we set the margin in _em_, the elements drift apart when we increase their font-sizes, owing to the compounding effect of _em_. But if we set the margin in _rem_, the spacing between the elements remains constant. 


**<u>Conclusion</u>**:
Many developers often use _em_ and _rem_ interchangeably to set padding and margin. But this can lead to unintended consequences, namely resulting in uneven spacing issues within the elements and in the layout of the website. That is why it's important to understand in what ways _em_ and _rem_ differ.

Let me know in the comments if this article has helped you understand the difference between em and rem better.