Using Rem and Em units is better than using px.
When we use px, it means that we hardcode the font-size to all of the users. The user can't change the value whatsoever. This actually troubles the user that wants to have a bigger font-size from the default 16px
How do rem works?
Rem and Em is a relative unit that many developers use to preserve accessibility.
Rem (root em) stands for "root element's font-size"
Usually, the default root font-size is 16px
. So, if we see a font-size that is 1rem, we are looking at 16px
Because Rem means root element's font-size, we can also override the default value by using CSS like this:
:root {
font-size: 20px;
}
Because we changed the root font-size, now 1rem = 20px
What if we want to use value other than 16px?
We can get the rem value of a pixels by dividing it with 16px. For example, if we want to use a font-size of 20px, we will write font-size: 1.25rem
. Which is 20/16.
But it's so annoying ?!
Yep, using rem will make the development process longer because we need to calculate the rem value. But this gives some freedom to the user, and we are not messing with the accessibility.
They can change the font-size like this:
How do em works?
Em stands for "parent element's font-size"
Because css is cascading and inheritable, em will inherit font-size value from the parent element. For example, we have a parent div, and p tag inside:
<div>
<p>hi</p>
</div>
<style>
div {
font-size: 0.5rem; // 8px
}
p {
font-size: 1em; // ??px
}
</style>
Because p
inherit the parent element's font-size, so 1em = 8px
. This means, that the p
will have font-size: 8px
.
That kind of confusing right? That's why using em for font-size is not recommended.
Always use REM for font-size to be consistent.
Where can we use em unit?
Because of the inheritable, em unit will be helpful for padding and *margin. By using em, we can make the padding and margin scale proportionately
For example, we are making a button. The button can have different font-sizes in mobile and desktop view. We can see the difference between rem and em on this codepen:
As we can see, by using em the padding stays proportionate to the scaling of font-size. Whereas rem has the same padding value on any font-sizes.
Can't we really use px anymore?
For me, usage of rem and em will be very good on the elements that are crucial like font-size, padding, and margin. But, when giving out border-width, I do still use px value because the value we give is so small that it is almost not noticeable if we change the root font-size.
Summary
There you go. Try to always use rem for font-size. And utilize the benefit of em for the proportionate padding if you need to.
Originally posted on my personal site, find more blog posts and code snippets library I put up for easy access on my site 🚀
Top comments (21)
IMO:
px
) - Relative border width is ugly.em
) - When inline with text.rem
) - Case for margin between heading and paragraph.em
) - Case for different button size.em
or%
) - Case for heading font size and secondary font size.px
) - It is the root! Why bother with relative units? Relative to what??em
orrem
) - Because it needs to be relative to the font size. Unless you want to set a vertical rhythm and such.Making the root font size a px (or vw/vh) value can break accessibility for some who change the font size through their browser settings.
Also line height can be kept unit less which acts like ems. ie:
line-height: 1.5;
But otherwise I agree! 😃
Agreed with Dillon! Thanks for your addition.
thanks to your great summary
This doesn’t make sense. Only if you set the root font size to 20px. Set it to 62.5% which usually means ~10px then you can use a very clear and intuitive 1.5rem = 15px etc. It takes 0 reasoning time
Awkward… I think you mean ‘We really can’t is px anymore?’ - you don’t need a ‘do’ here
Not just the parent… it’s closest common ancestor with any explicit font size value. So even if it’s container or container’s container had an explicit font size set, it will use that value
Careful, because that will catch some people out.
thanks for the addition!
not really a fan about this, because in designing usually we use 8px grid, so sticking to 16 probably will make the design more consistent. Using 10px rem hack will make the numbers awkward (0.8rem, 1.6rem), I rather use (0.5rem, 1rem).
Hmmm, you simultaneously complain about 'slowing down the development process' with 'difficult maths' but you won't make it easier for yourself to know exactly what the REM refers to...
Good luck with that!
Cool! Looking forward to see a blog/your work with that approach. By the way, using the 62.5%, do we have to redeclare all default font sizes? Considering that now the p default font size is 10px.
My approach for a while has been:
:root { font-size: 62.5% }
body { font-size: 1.6rem }
That way the user can still change the browser’s font size if needed, Rems are easy to reason on (1rem = 10px) AND all you still have the 16px default size.
Right. I thought this was standardised a while ago in this fashion
There is no standard lol the only baseline is that generally the browser starts at a 16px size. Each library or reset or normalize you use is just normal css someone wrote. They had to make a decision with this root font size but from what I’ve seen most just leave it at the default.
Who said anything about 'normalize' or'resets'? Not sure it was ever related to a CSS reset. 16px is an awkward unit to reason about. When I said 'standardised', perhaps 'convention' would have been more reasonable -- an approach adopted by many many developers.
Just do a search for
css 62.5%
and you'll find tons of articles about the technique, dating as far back as 10 years ago. , just another thing in a front-end devs toolbox to speed up development and forget about it.I bring up css libs and resets because a lot of devs (particularly newer devs) use them and likely assume that whoever made it "is doing it right". I wanted to point out that this assumption isn't true in this case (and many others).
I agree its a convention but not one set up default anywhere.
The way I do it today:
rem
for main textem
for things around main text: icons, button padding, secondary text in:before
etc.px
for anything else, which is the bulk of my app.em
.💪⚡ The power of the almighty inheritance is in the palm of your hands, and you give it up?
the reason why I'm still using px for borders is that you typically don't want float numbers in pixels that are this small as some displays won't show them properly and will have to round to the nearest value. 0.1rem for example would default to 1.6px, which can look odd on some screens
Definitely, thanks for your addition!
Not really, when you use your browser zoom entire content zooms.
If you use postcss a very handy plugin called px2rem can automatically replace px values with the calculated rem values.
Thanks, will look into it!
Useful post. @theodorusclarence kindly consider writing an article on Devopedia titled "CSS Units". Our moderators will help you if you need help.