Photo by Jeffrey Leung on Unsplash
Choosing the Right CSS Unit: A Comprehensive Guide to px, percentage, em, and rem
Tips and best practices on how to use px,%, em, and rem.
Table of contents
Introduction
One of the struggles many front-end developers face at the beginning of their careers is not knowing which CSS unit to use. let's face it there are way too many of them. You start out using pixels Px
and everything is going great until you come across a bunch of these other units because now you have to make your websites “Responsive”. Alas! the struggle begins.
Making the switch from px to other units like Em, Rem, percentages, Vw, Vh, Ex and Ch to mention a few is a tad bit challenging at first, however, these units aren’t as intimidating as they seem. As a beginner, you just need a handful of them under your tool belt and you're good to go.
By the end of this article, you would be confident in your use and understanding of percentage %, Em and Rem as they are the units you would find yourself using the most, and you will be well on your way to writing CSS that is scalable and responsive.
Pixels
This is the unit you're most likely familiar with, it is easy to use and very straightforward. px
units always behave the way you expect them to, if you declare something as 1px
, 2px
, or 30px
it is always going to be exactly as you set it, there are never any surprises. Pixels px
are units that are called Absolute units.
Absolute units are stand-alone units, they are not in reference to or relative to anything else. They are fixed-sized units and therefore they are not scalable. They always appear the same size no matter where the user views them.
Absolute units such as Pixels are terrible for making responsive websites. Consider a case where a user tries to bump up the size of things on your website by changing the default font size on the browser, they would notice that nothing changes on your website because you have set everything in a unit that is not scalable, and that can lead to a very frustrating user experience.
Notwithstanding, pixels can be used for things that do not necessarily have to be scalable such as borders, box-shadows, and for setting max-width
on containers.
Percentages %
A percentage is a type of unit known as a Relative unit.
Relative units are units that are always relative to something else, possibly the parent element or the viewport. They have dynamic flexibility, they can resize and scale according to the parent element's width or font-size value. They are very important to responsive design. If you build your website using mainly relative units, when a user changes the default font-size
on the browser everything would scale accordingly, leaving your website looking as great as you built it and also satisfying your user.
A Percentage represents a fraction of something. The percentage unit is always relative to something else either the width of its parent element or the width of the body
. The percentage unit is used when you want an element to be fluid and scale properly.
You can use the percentage %
unit to create flexible containers and flexible images. If you set the width of an element to be 40%
of its container, it is always going to take up 40%
of the width of its container regardless of if you scale up or scale down the browser window.
Here’s a link to a codepen where you can play around with percentages and see how it works in real-time to further enhance your understanding. Try changing the percentage values and resizing the browser window for you to see the full power of percentages.
Em
Em is also a relative unit. It is relative to the font size of its parent element. Em units can be used to set dynamic font sizes that are relative to their parent's font-size
.
The Em unit is useful because it helps everything scale proportionally.
Think of em
as a multiplier, that means, if you set an element's font-size to 1em
, 1em is 1 * the inherited font size from the parent
. Perhaps the parent's font-size
is 20px
, 1em
would be equal to 1 * 20
which is equal to 20px
, 2em
would be equal to 2 * 20
which is 40px
and 1.5em
would be equal to 1.5 * 20
which is 30px
and so on. Em values increase relative to the font-size value of its parent.
parent{
font-size: 20px;
}
/* The font-size in em is mutipled by the parent's font-size*/
.child1{
font-size: 1em; /* Here 1em = 20px */
}
.child2{
font-size: 2em; /* Here 2em = 40px */
}
.child3{
font-size: 1.5em; /* Here 1.5em = 30px */
}
Most of the time when you want to set a font-size
on an element, you would most likely have the value in your head as px
, if you want to convert that value to an em
value, all you need to do is divide your desired px
value by the parent elements pixel value. To give an instance, if the parent font-size value is 16px
and your desired value is 30px
, to convert 30px
to em
, you would divide 30 by 16 30/16
which is 1.875em
. If you’re like me and you hate math or you just want to save time, you can use this px
to em
unit converter by w3schools to get your desired em
value.
parent{
font-size: 18px;
}
.child{
font-size: 2.2em;/* 40px/18px = 2.2em */
}
If you set a font size in em it would inherit its value from its parent. If the parent of the element does not have its font size explicitly stated then it would go ahead and inherit a font size from its ancestors. If the ancestors also do not have a font size explicitly stated it would then inherit from the browser's default font size which is usually 16px
.
Em units can also be used for margins and paddings. Using em
for setting margins and paddings works quite differently from using em
to set an element's font size. The em
value you use on padding or margin on an element is relative to the font-size
of that element and not the font-size
of the parent. If the element does not have a font-size set, it would inherit the browser's default font-size
earlier stated as 16px
.
parent{
font-size: 18px;
}
.child{
font-size: 2.5em; /* 2.5 * 18px = 45px */
padding: 1em; /* here 1em = 45px not 18px. */
margin: 2em; /* here 1.125em = 50.6px not 20.25px. */
}
Note: Since font sizes set in em are inheriting the parent elements' font-size value, it can lead to a compounding issue when dealing with nested elements thereby causing things to behave strangely or not behave as expected. It can make things larger than they should be. An em
value can compound from one level to another. For this reason, Rem was created to save the day. I would be telling you about the Rem unit shortly
container{
font-size: 1.125em; /* 18px */
}
parent {
font-size: 1.5em; /* 27px */
}
.child{
font-size: 1.5em; /* 1.5em is 40.5px because the value is scaling relative to its parents value and its parent font-size value is scaling relative to the container's font-size value. The value is compounding*/
}
It is highly advisable to ditch em units for font sizes and use them mainly for margins and paddings. Margins and paddings set in em values do not experience the compounding issue as it is inheriting their value from the font-size
of the element itself and not its parent.
Rem
The Rem unit is short for Root em. Rem is similar to em
in that, it scales relative to another font size.
The main difference between em and rem is that the rem unit is always relative to the root <html>
element font-size
instead of the parent element font-size
, hence the name. Remember, most browsers set the default root font size to 16px
.
Note: If you set the root <html>
font-size
yourself in your CSS, then the rem value would be relative to the value you set and not the value from the browser.
Rem is also a multiplier and the value is calculated the same way em is calculated. 1rem is equal to 16px. See below for a brief refresher on the calculation or once again you can use this px to rem converter by W3schools.
1rem = 16px
To convert px to rem
Desired px value/ 16px or root
<html>
font-size value
Rem provides a more reliable way to determine your font size value. It is always going to be relative to one value which is the font size of the root <html>
element therefore eliminating the compounding issue. It is good practice to always use rem for font sizes.
In summary
Pixel units are absolute units they are not good for responsiveness. Use px for things that aren't scalable e.g borders,
box-shadow
, andmax-width
.Relative units are best for responsive design.
Percentage
%
units are good for flexible containers and flexible images. Use them when setting widths.Em is best for margins and paddings. Helps with proportional scaling.
Rem is best for font sizes. There is no compounding and it is more predictable.