The units used in CSS for defining the size like font-size, width, height, border-width, border-radius, etc. can roughly be categorised into 4 different types
- Absolute units (px)
- Font-size relative units (rem, em)
- Parent size relative units (%)
- Viewport relative units (vw, vh)
Absolute units (px)
Absolute units in CSS are those units which are constant and don’t change depending on font-size of element or parents, default font-size of browser, size of parent elements, viewport size etc.
These include physical units (‘in’, ‘cm’, ‘mm’, ‘pt’, ‘pc’) (Yes these exist, look them up for more info. They aren’t complicated ‘in’ stands for inches, ‘cm’ for centimeter, etc) and ‘px’. The physical units are generally used on print media and high resolution devices and are not very commonly used in day to day web development. On Desktop screens and lower ‘px’ is the recommended absolute unit, which as you already know is more commonly used.
More info on px itself can be looked up here we are more concerned about when to use it.
Use of px should be kept to minimum as we would want most of spacings, fonts, element sizes to scale according to browser default font-size or root font size (we’ll discuss this more in relative units). When font-sizes, width, height, etc are specified in px they are not scaled with browser default font-size it means the users who would want to see them in larger size see them the same as regular users. This causes accessibility problems. Lets say we have a user who has trouble reading smaller fonts, he/she usually sets the browser default font size to higher value. When we use px we are overlooking such users.
Hence use px only when we don’t want to scale something with browser default font size.
Font-size relative units (rem, em)
These are the units that need to be used more often at component level. These include ‘rem’, ‘em’ and ‘ex’ (Yes there is something called ‘ex’ which is not as popular, look it up to know more).
’rem’ is a unit relative to Root font size ,i.e. the font size of html element of the document and when used on html element itself its relative to browser default font size. Initial font size of html element is equivalent to default font-size in browser settings. When setting the value of html I recommend not to use ‘px’ as we would want root font to be relative to browser default font size.
Most browsers have browser default of 16px font-size. So lets say if we specify 1rem font-size on html element that would be equivalent to 1×16 px = 16 px. And instead if we specify a 2rem font-size on an element when there is no font-size( or 1rem font-size) set on html element that would be equivalent to 2x16px = 32px. ‘rem’ when used on properties other than font-size is very similar, it still takes the values relative to root font size. e.g. when root font-size is 16px, if an element has a width of 10rem its equivalent to 10x16px = 160px width.
‘em’ unlike rem takes the font-size relative to parent font-size i.e. if an element has font size of 2em when its parent font-size is equivalent to 15px(it could be ‘rem’ or ‘em’ equivalent of 15px), then the font size of element is equivalent to 2x15px = 30px. When used on properties other than font-size like width, height, border-width, etc. ‘em’ is a unit relative to element (not parent) font-size. i.e. if we have an element with font-size of 20px or equivalent (i.e. rem or em equivalent of 20px) , then a width of 10em on it would be equivalent to 10x20px = 200px.
Parent size relative units (%)
% are more commonly used on width and height properties. As you would have guessed they are relative to parent size. i.e. width: 50% would mean 50% of width of parent and height 50% (**doesn’t work normally, because height of a block level element depends on its content. Please see the note below the example image) would mean 50% of height of parent. One of the exceptions to this is absolutely positioned elements, which take the % sizes relative to closest parent with relative positioning.
Also note that on absolutely positioned element, % values of ‘top’, ‘bottom’ are equivalent to percentage of height of closest relatively positioned parent and % values of ‘left’, ‘right’ are equivalent to percentage of width of closest relatively positioned parent.
**Note: In the above example where height is specified in % the element has position of absolute, in this case the percentage is w.r.t the height of closest relatively positioned parent. In most cases % when used on height doesn’t work unless there is appropriate positioning used on the elements.
% units are more useful for creating structure and layout of UI components.
Viewport relative units (vw, vh)
‘vw’, ‘vh’ are units that are relative to users browser viewport. 100vh is equal to full height of browser viewport and 100vw is equal to full width of browser viewport. These units can be especially be useful when we have an element whose position relative to view port is fixed. E.g. A side menu bar can be made to have a “height: 100vh” and “position: fixed” as it always takes full height of screen and is at the same position relative to viewport.
Also ‘width: 100vw;’ can be used on components like sticky header which has ‘position:fixed’ on it to make it occupy full width of the screen.
The calc function
Now, we sometimes might need to set properties like width in combination on above mentioned units .e.g. I have come across situations where I needed to set width as 5em less than 100%. ‘calc’ function is a very useful function for specifying properties in combination of these units.
width: calc(100% - 10rem);
There are some other interesting units where are not commonly used like ‘vmin’, ’vmax’, ’ch’ that you could explore. Also note that we have only explored some of the use cases of these unit, depending on which property and type of element the unit is used on there are always exceptions.