Photo by William Warby on Unsplash

CSS Units: Which Ones To Use And Avoid

An explanation on CSS units with examples to get you going

Daan
Daan
Aug 12, 2019 · 7 min read

Since there are so many different units in CSS, it can be quite overwhelming. Most developers know how to work with pixels and percentages, but there are many more CSS units that can be used. Some of the CSS units that we will handle in this article are em, rem, fr, ch, vw and vh. You will learn which CSS units you should be using and why you should be using them. And you will also learn why you should not use certain units.

The units

Let’s start by going over each unit and explain where it’s specifically good for.

Pixels

Pixels are the basic building block for everything in CSS. Strangely enough, pixels shouldn’t be the unit of choice most of the time. Pixels are very straightforward, they say what they are going to do.

Take a look at the example below. This will render a 500px block with a red background that has a 14px font-size paragraph in it. If you wanted to make the div a little smaller, all you have to do is change the width to 250px, for example. You want the font-size a little bigger? No problem, just change the font-size to 16px.

<div>
<p>This is some text..</p>
</div>
div {
background-color: red;
width: 500px;
}
p {
font-size: 14px;
}

See how easy it is to change the styling with pixels? Pixels are very straightforward. And because of that, it is very tempting to use them. This will bite you if you continue to use pixels throughout your entire application. This is because pixels are really bad for accessibility. An easy example to demonstrate this is by changing the font-size in your browser. If you change the font-size nothing will actually happen with the font-size in your application. That is because we have set the font-size to 14px, no matter what. The CSS that we have defined will not respect the font-size setting of the browser. What pixels are good for is when you want something to look exactly the same width and height despite the user's browser settings. A good use case for pixels is when you are defining a border. You probably want that border to always be the same. But most of the times you don’t want to use pixels for defining layouts and font-sizes. So what should you be using?

Rem and em

In most cases you would want to use the rem unit. But what is a rem unit? One rem unit is the font-size is that you have defined on the html element. The “r” in rem stands for relative.

html {
font-size: 10px;
}
p {
font-size: 1.4rem; // This would be 14px (1.4 * 10px)
}
h1 {
font-size: 2.2rem; // 22px
}

Now that we know what the rem unit is, we can rewrite the div with the red background of the first example. Both the width and the font-size are now relative to the font-size of the html tag.

html {
font-size: 10px;
}
div {
background-color: red;
width: 50rem; // This comes down to 500px
}
p {
font-size: 1.4rem;
}

But what about em’s?

The em unit works exactly the same as the rem unit, but em’s don’t take base font-size into account. Em’s use the font-size of their current element. Let’s take a look at the following example:

html {
font-size: 10px;
}
div {
background-color: red;
font-size: 0.5em; // This will be 5px (10 * 0.5)
width: 50em; // This will be 250px (5px * 50)
}

The width of the div gets defined by its own font-size, instead of the html tag’s font-size.

Using a combination of em’s can get very tricky. Imagine the situation where a child sets the font-size to em and the parent of that child sets the font-size to 0.5em. This can get messy really quickly. Especially when you imagine the situation where multiple elements are nested, all defining a font-size in em.

When using this solution to define sizes, the same problem occurs as when using pixels. It doesn’t respect the browser settings. That is because we hard-coded the font-size of 10px on the html element.

What you can do to work around this problem is set the font-size on the html element to font-size: 62.5%;. The reason that this works is that almost all browsers have a default font-size of 16px. This gets you to a 10px base font-size that does respect the browser settings and makes the application more accessible.

Note:
Safari sometimes does strange things with rem’s in media queries. There might be some circumstances where you want to change them for em’s. Just make sure to check the styling of your application in Safari.

Percentages

Just like pixels, percentages are pretty straightforward. The percentage is always looking at the size of its parent. This means that in the example below the second div will be 50% of its parent, which comes down to 30% of the page width. That is because the parent of the second div, the first div, is 60% of the page width.

<div>
First div
<div>Second div</div>
</div>
div {
width: 60%;
}
div div {
width: 50%;
}

Since we used percentages it is going to be responsive pretty nicely, by default. Try resizing your browser’s width. This would not be responsive if you used pixels, rem or em to define the widths. What is nice about the usage of percentages, is that when you change the parent’s width the children will still behave in the same way. Percentages are very useful for defining layouts.

It is good to know that the behavior of percentages change in combination with position: absolute; and position: relative;.

Flexbox
When defining a div with the display: flex; style it automatically calculates the space and gives each child an equal width.

<div class="container">
<div>Div one</div>
<div>Div two</div>
<div>Div three</div>
</div>
.container {
display: flex;
background-color: red;
}
.container div {
background-color: blue;
}

You can also give the .container div a fixed width of 20%, for example. This will give every div inside the container a width of 20% of the container. This means that there will be a space leftover of 40%. Percentages are a very good way to get going with flexboxes.

Fr

Fr, or fractional unit, is a relatively new unit in CSS. This unit is often used in combination with grids. Let’s take a look at the grid we defined in the example below.

<div class="grid">
<div>Div one</div>
<div>Div two</div>
<div>Div three</div>
</div>
.grid {
display: grid;
grid-template-columns: 1fr 2fr 2fr;
background-color: red;
}
.grid div {
background-color: blue;
}

The column sizes get defined by the grid-template-columns property. There is a total of 5fr, which means that 1fr will come down to 20%. This means that the column widths will be 20%, 40%, and 40% respectively. Fr is a really nice unit to use because it takes a lot of the math out of the way. You can change the amount of fr’s in the grid and the size of 1 fr will automatically get figured out for you. This is why you could, and maybe should, prefer them over percentages when defining a grid.

Ch

The next unit that we are going over is the ch unit, which stands for the character width. The character width of the “0” (zero) character defined in the font, to be more precisely. So however wide the “0” character is in a given typeface, that’s the measure of one ch. This means that there is a difference between the behavior of the ch unit in monospace and proportional fonts.

In a monospace font, where each character has the same width, you can use the ch unit to make sure that 100 characters fit on one line, for example. In proportional fonts every character can have a different width, which makes it impossible to fit exactly 100 characters on one line.

<div class="one">
<h1>Courier</h1>
<span>Lorem ipsum dolor amit etc</span>
<span>abcdefghijklmnopqrstuvwxyz</span>
<span>12345678901234567890123456</span>
<span>mmmmmmmmmmmmmmmmmmmmmmmmmm</span>
</div>
<div class="two">
<h1>Arial</h1>
<span>Lorem ipsum dolor amit etc</span>
<span>abcdefghijklmnopqrstuvwxyz</span>
<span>12345678901234567890123456</span>
<span>mmmmmmmmmmmmmmmmmmmmmmmmmm</span>
</div>
.one {
font-family: Courier;
}
.two {
font-family: Arial;
}
span {
width: 26ch;
display: block;
background-color: red;
margin: 0.25rem 0;
}

Which results in:

The ch unit comes in handy when you want the width to tightly relate to the font that you use. But note that this width per character differs when using a proportional font.

Vw and vh

The vw and vh units, which stand for viewport width and viewport height, are the last units that we will go over. No matter where you are, inside a child or in a grand grandchild, the vw and vh will always be the width and height of the viewport. The vw and vh don’t care about the size of its parent.

<div>
Div one
<div>Div two</div>
</div>
div {
width: 50%;
}
div div {
width: 100vw;
}

The child div will be 100% of the viewport width, despite its parent's width being 50%. The same goes for the vh unit.

The Startup

Get smarter at building your thing. Join The Startup’s +724K followers.

Daan

Written by

Daan

Backend developer from The Netherlands. Crypto enthusiast.

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +724K followers.

Daan

Written by

Daan

Backend developer from The Netherlands. Crypto enthusiast.

The Startup

Get smarter at building your thing. Follow to join The Startup’s +8 million monthly readers & +724K followers.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store