Carmela BeiroJul 27, 2017

Px, EM or REM

In CSS there are different units of measurement that can be used for expressing length, among which are pixels, EMs, REMs and percentages. So this raises the question, which one of them should be used?

Pixels (px) are the simplest and most commonly used unit of measurement by developers. They are great for getting pixel perfect designs as they are absolute length units, they always represent the same fixed size. The main drawback of establishing sizes in px is that the resulting designs don’t respect the font size established by users in their browsers. Users could still zoom in and out, but in the end we are not developing a fully accessible web page.

That’s where EMs and REMs become useful as they are scalable units of measurements providing flexibility to web designs. They present certain differences than can help understand in which cases each one of them should be used.

EMs

EM unit is a relative measure of length, and refers to the width of the capital letter ‘M’ of a given element. For example, if the element in which em is applied has a font-size of 16px, then 1em will be equal to 16px. It’s a common mistake to think that EMs are relative to the font-size of the parent element. In fact the em unit is relative to the current font-size of the element where the style is being applied, which in turn can be inherited from the parent’s font-size given the nature of CSS. Let’s see an example:

Suppose we have the following structure in HTML:

<body>
    <div>
        <span> Hello </span>
        <p> World </p>
    </div>
</body>

and we define the following styles for it:

body {  font-size: 1em }
div {  font-size : 1.3em }
p { font-size: 1.3em }

By default, browsers set the font size to 16px, thus the 1em in the body’s font-size is equivalent to 16px. Then we have the div, and it’s font-size is set to 1.3em. That is, 30% greater than the current div’s font-size, equivalent to 20.8px (16px * 1.3 = 20.8px). At last we have the p element with also a font-size of 1.3em, but in this case, the font-size inherited is 20.8px, thus the font-size of p element is 27.04px (20.8px * 1.3 = 20.8px).

Additionally, if we want to add another attribute such as margin, padding or line-height to the p element using em units, the measures will be relative to the current font-size of the p element (27.04px), so for example a margin-bottom with 1em will be equivalent to 27.04px.

p {
  font-size: 1.3em;  /* 27.04px */
  margin-bottom: 1em /* 27.04px * 1(em) = 27.04px */
}

REMs

REM means “Root em”. The key difference with em is that it depends on the font-size of the root html element instead of the font-size of the element where the style is being applied. This means 1rem is always equal to the font-size defined in the html element. Coming back to the previous example, assuming that the default font-size of the browser is 16px and it hasn’t been changed, if we define the CSS style attributes in rem they will have the following values:

body {
    font-size: 1rem; /* 16px*/
}

div {
    font-size : 1.3rem;  /* 16px * 1,3(rem) = 20.8px */
}

p {
    font-size: 1.3rem; /* 16px * 1,3(rem) = 20.8px */
    margin-bottom: 1rem;  /* 16px *1(rem) = 16px */
}

Different ideas

There are many different approaches in how to combine unit measurements in order to achieve a fully scalable website. For example, we could choose to use only rem units in our code as they are less complex than em units. The problem with this is that it makes it difficult to create modular components. Suppose we create a header component, and define it’s height, vertical padding and line-height in rem. If we afterwards want to change the font-size of the header we would have to adjust all these attributes accordingly, as they would probably lose its proportions. On the other side, if we define the header’s attributes in EMs, they would depend on the font-size of the header and they would proportionally scale without needing to modify anything.

On the other hand, we could think of using only em for all measures, including font-size, padding, margin and component widths. This could lead to problems with the design and layout of the site. As an example, if we want all the components to have the same horizontal padding in order to be aligned, we would find it hard to do this with em as they would all depend on different font sizes. But if this attribute is set in rem, they would all have the same value making the design more flexible as it is easier to change. The same could happen with gutter widths between items, so we could set the margin in rem to behave consistently between components.

Given the potential problems that may arise from using only EMs or REMs, we must look for alternatives in order to take full advantage of these units. We are currently working with an approach in our designs that is giving good results and combines different unit measures. This consists of:

  • Using em units for font-size and properties where the font-size directly affects the design of the component, such as line heights, vertical paddings, among others.
  • Use rem for the rest of the properties, such as components margins, horizontal paddings, in order to maintain the consistency of the design.
  • As for component widths, they could be defined both in em or rem units, but we probably want this to be affected by the width of the parent element instead of its font size or the font size of the root element, in order to create responsive designs. That’s when percentages come in handy, as we use them to define widths according to the size of the screen.
  • Vary the font size of the root element according to the size of the screen. We do it with percentages but it can be done with any relative unit measure.

Hope you find this technique useful for your projects!