Relative Units

In the last lesson we discovered the limitations of using pixels, and I showed an example of using a percentage to make the container relative to the size of the viewport. In this lesson we’ll take a look at our relative units and how they are used for layout.

The CSS Layout Workshop: Relative units

What is a relative unit?

A relative unit gets sizing from something else. In the specification the relative length units are defined as em, ex, ch and rem. These are font-relative lengths. The specification also defines a % value, which is always relative to another value. Using relative values means that things can scale up and down according to some other value.

Percentage units

A container directly inside the viewport with a width of 90% will always be 90% of the available width - whether I am on a phone or high resolution display.

If I have another container inside that first container with a width of 50%, it takes 50% of the width of the parent element and not the viewport.

<div class="wrapper">
  <p>This div takes up 90% of the viewport width to a maximun of 940px.</p>
  <div class="inner">
  <p>The nested div is set to 50%. This makes it 50% of its direct parent.</p>
  </div>
</div>
.wrapper {
  width: 90%;
  max-width: 940px;
}

.wrapper .inner {
  width: 50%;
}

As you will discover in the lessons on responsive design in the CSS Layout Fundamentals course, percentage units are a key component in the flexible grids needed for responsive design.

The font relative units em, ex, ch and rem

The first of these units are most of interest when it comes to the typography in your designs. The rem and em units however, while referring to font sizes, can be very useful in creating flexible, scalable designs.

ex

The ex unit refers to the x-height of the font. Typically the size of the letter x in that font.

ch

The ch unit refers to the width of the ‘0’ (zero) character in the font for that element.

em

Using ems as a length unit in layout, and in particular in padding and margins can help to maintain a vertical rhythm. If a user resizes their text or you decide to make font sizes larger or smaller in your stylesheet, the em length unit will scale proportionately. In this example I am using ems for the padding on the box. The padding remains in proportion as I resize the font.

<div class="box1">
  This box has padding set to 1em, and has a font-size of 20px. 
</div>
<div class="box2">
  This box also has padding set to 1em, and has a font-size of 40px.
</div>
.box1 {
  width: 300px;
  font-size: 20px;
  padding: 1em;
  border: 4px solid #ccc;
  margin-bottom: 20px;
}

.box2 {
  width: 300px;
  font-size: 40px;
  padding: 1em;
  border: 4px solid #ccc;
}

Using em for the width of elements can ensure that a box containing some text increases in width as the font size increases. If I change the widths on the boxes in the example above to ems the boxes now increase in width as their font size increases.

.box1, .box2 {
  width: 20em;
}

The em size is relative to the font size on the element in question. This can make ems a little tricky to use. If elements are nested or appear in different contexts in your document you can find that text or elements sized with ems can appear much smaller or larger than you imagined. In the example below both nested boxes have the same class, setting a width of 10em. However that 10em is much wider in the second box because the parent has a larger font-size.

<div class="box1">
  This box has padding set to 1em, and has a font-size of 20px. 
  <div class="inner">
    <p>This box is nested inside box 1, with a width of 10em.
  </div>
</div>

<div class="box2">
  This box also has padding set to 1em, and has a font-size of 40px. 
   <div class="inner">
    <p>This box is nested inside box 2, with a width of 10em.
  </div>
</div>
.box1 {
  width: 600px;
  font-size: 20px;
  padding: 1em;
  border: 4px solid #ccc;
  margin-bottom: 20px;
}

.box2 {
  width: 600px;
  font-size: 40px;
  padding: 1em;
  border: 4px solid #ccc;
}

.inner {
  width: 10em;
}

rem

The rem (root em) unit is the font-size of the root element, which is usually the html element. As with em, you can use this value as a length unit and it will always remain relative to the root element. You don’t get the nesting issue as we saw with em. This makes it easier for you to set sizes relative to a font size declared on the root element, no matter what context the element is in.

If we change the previous example so that .inner has a width of 20rem the width will be the same for that element no matter what the font-size of the parent is. To change that size we adjust the font size of the html element.

.inner {
  font-size: 20rem;
}

Browser support for the rem unit is good unless you need to support IE8. What you can do however is declare a font-size in pixels and then immediately afterwards in rems. IE8 will see the pixel value and use that, ignoring the rem value it doesn’t understand. The CSS cascade then takes effect for other browsers and they use the last value declared which is the rem value.