Already purchased? Login →

How to set font sizes in CSS

There are lots of ways to set the size of text in CSS. px, em and rem are the most popular options, but what’s the difference between them?

Pixels (px)

Pixels are an absolute unit of measurement in CSS. That means that if a user writes font-size: 16px the output will be text at 16px.

Pixels are an easy option, but they create accessibility issues. Users who need to increase the browser’s default font size won’t be able to when the font size is set as pixels.

Ems (em)

em is a relative unit of measurement. That means its size is relative to something else, but what?

em units are relative to their parent element. 1em is the same as the current parent’s font size.

If the parent element’s font size is 16px, 1em would be 16px. That seems simple, but how does it work in practice?

If you had the following CSS:

body {
    font-size: 16px;
}
p {
    font-size: 1.5em;
}

And this HTML:

<body>
    <p>What size will this text be?</p>
</body>

The p text would be calculated as 1.5em x 16px = 24px. The parent of p is body so the value of em (1.5) is multiplied by 16px.

You can see that in this Codepen – experiment with some different values, too.

See the Pen Boxes – Example #1 by Dave Smyth (@websmyth) on CodePen.

Root font size

To make these examples easier to understand, they all use a pixel value for the body font size:

body {
    font-size: 16px;
}

For accessibility reasons, it’s better to set the root font size at the html level and set it as a relative unit:

html {
    font-size: 100%;
}

Ems and nesting

This works well as the text will scale up and down if a user changes the default font size, but it can be confusing. What happens if there are several nested elements?

If our HTML looked like this:

<body>
    <article>
        <p>What size will this text be?</p>
    </article>
</body>

And had the following CSS:

body {
    font-size: 16px;
}
article {
    font-size: 1.5em;
}
p {
    font-size: 2em;
}

How is the p font size calculated? Here’s what happens:

The article font size is calculated as 1.5em x 16px (the font size of its parent, body). That gives article a font size of 24px.

The p font size is calculated based on its parent font size. Its parent is article, so 2em x 24px = 48px.

You can see that in action here:

See the Pen Boxes – Example #1 by Dave Smyth (@websmyth) on CodePen.

Rems (rem)

This is where the rem unit comes in handy. rem units work in exactly the same way as em units, except for one key difference:

The calculation is based on the root element, not the parent. That’s what the r stands for.

Returning to our example from above, the final font size of p would now be 32px because the calculation is now 2em x 16px (the value set at the root, which is html).

See the Pen Boxes – Example #1 by Dave Smyth (@websmyth) on CodePen.

The rem unit allows font sizing to scale but it’s also predictable. You no longer have to worry about the impact of parent element sizes, so they’re the best of both worlds.

Found this useful?

Early access to the course is available now at an introductory price of £159.

£159 – Buy Now

Want a reminder?

If you would prefer to wait until the course is released, sign up to be the first to know when it’s completed.

Remind me