Using REMs exclusively for measurements in CSS is a handy tool for enforcing a stronger design system.
Design systems are inherently difficult to manage as projects grow. The higher the number of scenarios, the more complex the nuance of maintaining consistent components across the ecosystem becomes. In other words, as projects grow, it can quickly become a challenge to maintain a consistent sizing approach throughout the system.
There are many approaches out there that work to solve this challenge, but often they only serve to complicate the problem.
Take Bootstrap 4.1's sizing utilties for example. Bootstrap uses a set of size factors ranging from zero to five, but they don't really mean anything other than being relative to one another. And what if you really want a size larger than the largest, or in between one of the sizes? The solution immediately breaks down.
What we often overlook when solving these system-wide challenges is that we have the tooling for it right out of the box with CSS. CSS has a unit of measure,
em and another related unit,
em is defined by MDN as follows:
1em is the same as the font-size of the current element (more specifically, the width of a capital letter M.)
The rem (root em) works in exactly the same way as the em, except that it will always equal the size of the default base font-size; inherited font sizes will have no effect
So we have a scaling tool always at our disposal in
rem. Personally, I use
rem exclusively unless I come across a scenario in which sizing needs to be relative to a component (or module) within the system and not the system as a whole. This rarely occurs -- for me, the sizing can almost always be built atop the entire system.
In other words, if we set our root element (or body) to have a font-size of
16px (which tends to be the standard), then all
rem units are relative to that. For example:
margin-bottom: 1rem; /* Equivalent to 16px */
Therefore, if you use
px as the measurement for the base size (
rem units are automatically relative. No need for a sizing factor system because you have one just by using
rem units along with some discretion.
Now, you can quickly complicate your system depending how fine-grained you allow yourself to be when using
rem units. You can use decimal units in
rem, so if you want font size to be
15px instead of
16px you could, theoretically use
.9375rem as your measurement.
Don't do that.
If for some reason you need an specific pixel size, do one of the following:
rem(you'll want a media query for that, if necessary), but it will be a lot easier to understand your intention when reading your code.
.1rem. If you changed the measurement to
.9rem, that resolves to
14.4px, which can often be good enough when you really need to be just a touch different.
But, where possible, build a stronger system by using a larger fraction of the
rem unit as the smallest amount by which you can change a measurement. For example, on most projects I try not to use
rem any finer than
4px in the
16px-base system). So if the
1rem measurement needs to be just a little smaller, it goes to
.75rem first. And I only use
.1rem increments where absolutely necessary.
By taking this minimum fraction approach, you've done away with the fine-grained pixel-based system and are left with a more generic unit-based system. The benefits of this are grand! When you use larger measurements as the smallest unit, it becomes immediately clear when something is out of place. (e.g. It's easier to see when something is
4px off compared to being
Of course, there are ways to be clever with
rem units. Take Jonathan Snook's clever trick of using
62.5% as the base size of a
16px-based system. That effectively makes
.1rem equivalent to
1px. Cool, except then you're enticed to use
rem units just like you'd use pixels. That can be nice for understanding pixel translations, but then you have the nuance of a pixel-based system to solve for and you're right back at the beginning.
If you're going to use
rem to help control your design system, use it against the base measurement of the system. Forget about pixels when you can, and think of your smallest unit (e.g.
.25rem) as a generic amount by which elements can move on the page.