Units
Font sizes, block widths and spacing are set with a number and a unit: 16px, 50%, 2rem. Units are either absolute — always the same size — or relative, depending on something else: the parent, the font or the browser window.
Pixels
px is a pixel, the most straightforward absolute unit. A block 200px wide is the same inside any parent:
<style>
.box {
width: 200px;
padding: 10px;
background: lightskyblue;
}
</style>
<div class="box">200px wide</div>A CSS pixel is not necessarily one dot on the screen: on high-density screens one CSS pixel covers several physical dots. That is why 16px looks about the same on a phone and on a monitor.
Percentages
% is calculated from the size of the parent. A block with width: 50% takes half the width of its container, whatever that width is:
<style>
.parent { width: 300px; background: whitesmoke; }
.half { width: 50%; background: plum; }
</style>
<div class="parent">
<div class="half">50% of 300px = 150px</div>
</div>Percentages are handy for "fluid" blocks that stretch together with the window.
em
em equals the font size of the current element. If a button's font is 20px, then 1em is 20 pixels and 0.5em is 10. Spacing in em grows with the text:
<style>
.btn { padding: 0.5em 1em; background: gold; border: 0; }
.small { font-size: 12px; }
.large { font-size: 24px; }
</style>
<button class="btn small">Small</button>
<button class="btn large">Large</button>Both buttons are described by one rule, yet the large one also has larger padding.
rem
rem equals the font size of the root element — the <html> tag. By default that is 16px, so 1rem = 16px and 1.5rem = 24px. Unlike em, the value does not depend on where the element sits:
<style>
.title { font-size: 2rem; }
.text { font-size: 1rem; }
</style>
<p class="title">2rem — 32 pixels</p>
<p class="text">1rem — 16 pixels</p>A font size in rem respects browser settings: if a person enlarges the font, the whole site gets bigger. That makes rem a good choice for text.
Viewport units
vw and vh are one hundredth of the browser window's width and height. 100vw is the full window width, 50vh is half the height:
<style>
.strip {
width: 40vw;
background: lightgreen;
}
</style>
<div class="strip">40% of the window width</div>Resize the window and the strip changes with it.
Which unit to choose
| Unit | Depends on | Good for |
|---|---|---|
px | nothing | borders, small gaps |
% | the parent's size | block widths |
em | the element's font | padding inside buttons |
rem | the font of <html> | text size, spacing |
vw, vh | the browser window | large full-screen blocks |
Zero is written without a unit: margin: 0 means the same as margin: 0px.
Common mistake
The browser treats a size number without a unit as an error and skips the declaration. A space between the number and the unit is an error too:
<style>
.a { width: 200; background: tomato; }
.b { width: 200 px; background: gold; }
.c { width: 200px; background: lightgreen; }
</style>
<div class="a">width: 200 — did not work</div>
<div class="b">width: 200 px — did not work</div>
<div class="c">width: 200px — works</div>The exceptions are 0 and properties that need no unit, such as line-height: 1.5.