Guide to CSS Units for Relative Spacing
Tags: css, webdev
Published: 2020-02-15 22:40:43

## Space Relative to the Document `:root`

**Use**: `rem`

Unless you change it, the default `rem` value is `16px` with the advantage of responding to changes in zoom level.

### Why and how to use `rem`

`rem` will not change no matter how deeply it is nested, so for consistent spacing between/around elements, it is a reliable choice.

It is also the preferred measurement for font sizing.

{% codepen https://codepen.io/5t3ph/pen/PoqZgpw %}

## Space Relative to the Viewport

**Use**: Viewport units

The viewport is the boundary of the browser window or device screen size.

### Available viewport units

- `vh`: viewport height - based on the height of the viewport
- `vw`: viewport width - based on the width of the viewport
- `vmin`: viewport minimum - returns the smaller value of `vh` or `vw`, updating responsively
- `vmax`: viewport maximum - returns the larger value of `vh` or `vw`, updating responsively

Viewport units are ideal for:

- keeping the element within the bounds of the visible area
- ensuring `<body>`, `<main>`, or a splash header has a minimum height as tall as the viewport (`min-height: 100vh`)
- creating proportionate, responsive elements
- combining with `calc` to affect the visibility of multiple elements
- creating full-height, full-width slideshows (particularly [combined with `scroll-snap`](https://codepen.io/5t3ph/pen/gObVopj))

This example is of a nearly full-height header that makes use of `calc` to ensure a bit of space is left to hint at additional content:

{% codepen https://codepen.io/5t3ph/pen/RwPaRmE %}

## Space Relative to the Element

**Use**: `em`

`em` will stay proportionate to the element or nearest ancestor's `font-size` rule. One `em` is equal to the font-size, so by default, this is equal to  `1rem` which is by default `16px`. 

Compared to `rem`, `em` can compound from parent to child, causing adverse results. Consider the following example of a list where the font-size is set in `em` and compounds for the nested lists:

{% codepen https://codepen.io/5t3ph/pen/rNVeLdM %}

### When and how to use `em`

- between typography elements
- padding on textual components, ex. buttons or input fields
- for `letter-spacing`, typically as a micro value such as `0.03`, can also be defined negatively

In the following codepen, you can change the `$font-size` variable to see how it affects the `label` and `button` as a unit:

{% codepen https://codepen.io/5t3ph/pen/yLNOJEY %}

## Spacing Relative to Content

**Use**: `ch`, `em`

While `em` can be appropriate for spacing based on content, an underdog that doesn't see much action is the `ch` unit. This unit is equal to the width of the zero character in the set font-family.

### When and how to use `ch`

Use to set width based on the optimal line-length (50-80 characters depending on the resource used). Start with `80ch` and optimize as needed based on the font in use, keeping it mind most fonts have a narrow `0` so the `ch` will likely need to be larger than the line-length desired. 

This is great for:

- `article` content
- setting the `flex-basis` value, especially for the [flexbox albatross](https://heydonworks.com/article/the-flexbox-holy-albatross-reincarnated/) technique
- setting the "max" part of `minmax` for grid columns
- providing a `min-width` on buttons or navigation items

{% codepen https://codepen.io/5t3ph/pen/dyoMXQe %}