CSS is hard. Really hard sometimes.
Font size is something that seems simple on the outside, but I see products mess it up all the time.
You might wonder, who cares? It's just a font size, right?
Font size is a critical aspect of web accessibility. If you're not careful, you could find yourself getting sued.
TL;DR:
To get a better understanding of the tradeoffs and when to use which, continue reading!
I've found that newer developers tend to default to pixels. Understandably so — pixels are the most straightforward way to match a design and are easy to understand.
By the CSS Standard, 1 pixel is 1/96 of an inch.
However, using pixels as your unit for font sizes comes with a couple of downsides:
In CSS, the em unit is used to define the size of an element relative to its parent container or the font size of the element itself.
Em stands for "em-height", which traditionally refers to the height of the capital letter "M" in a given font. However, this definition has evolved to simply refer to the current point size.
For example, consider this example snippet of code:
❓ What size font in pixels do you think the Hello World gets rendered at? If you guessed 24px, you would be correct!
Let's break it down — take a deep breath, as it's a lot of math 😅
“Hello World”s font size is defined as 1em, meaning it will simply be equal to whatever font size it inherits.
In this case, its parent <body>
has a font size of 1.5em. We now need to go one more layer higher, to the <html>
tag to see that the <body>
tag will have a font size of 1.5 * 16px = 24px. And because the “Hello World” has the same font size as the <body>
, our “Hello World” will also be rendered at 24px.
Whew, that was a lot of math for a simple example!
Naturally, one of em's disadvantages is that it is harder to calculate. Its value is dependent on a variety of factors such as its inherited font size and its own font size.
In addition to this, it's hard to be precise since it's not a hard fixed value. If you need to specify a precise size of an element, such as a button or graphic, em units may not be the best choice.
The advantage of em comes in when there are any changes to the default document font size. Because these units are relative to the parent, any changes to the default document font size for accessibility reasons also scales any text using em.
In the above example, if 16px is changed to 32px, “Hello World” will automatically change to 48px even though the font size only changed in one spot.
Welcome rem, where em and pixels meet in the middle. Rem stands for “root em”, referring to the fact that Rem is relative to the font size of the root element (usually the <html>
tag).
For example, let's consider the above snippet, but replace em with rem.
❓ What size font in pixels do you think the Hello World gets rendered at?
Our calculation becomes much simpler compared to em. We know that the root element, aka the <html>
tag, has a font size of 16px. And because our “Hello World” is being rendered at 1rem,
it will simply be 1 * 16px = 16px. Much easier than needing to traverse up the tree to figure out what 1em is!
Similar to em, rem is not great for precise measurements or things that should be statically defined. Rem is also relatively new — if you need to support IE 8 or earlier, you would be best sticking to em.
This page uses rem. Try changing your browser's default font size and see how the text changes!
If you are using Chrome, you can change the default font size in Settings > Appearance > Font Size
We understand that the tradeoff of speed (using pixels) and accessibility is a tough decision to make. Sadly, most developers teams end up picking speed over accessibility.
This is a general rule of thumb, but hopefully this paints a deeper understanding of how these units work so you can make the correct tradeoff evaluations yourself!
At Magic Patterns, we want to make this tradeoff irrelevant. We believe that with the power of AI, development velocity should as easy as typing in what you want. And it should be accessible by default.
If you're interested learning how to use your custom design system with Magic Patterns, schedule a demo to speed up your development process.