Course outline · 0% complete

0/30 lessons0%

Course overview →

Units: px, %, em, rem, vw and vh

lesson 5-3 · ~8 min · 16/30

Absolute and relative units

A stylesheet written only in px breaks the moment anything resizes. Users raise their default font size, which is a common accessibility setting, phones vary in width, and text zooms.

Relative units exist so one set of styles survives all of that, and choosing the right unit is a real daily decision on working teams.

UnitRelative toGood for
pxnothing, it is fixedborders, small gaps, max-widths
%the parent's sizefluid layout widths
emthe element's own font sizepadding that scales with its text
remthe root (html) font sizefont sizes and spacing
vw and vhthe viewport width or heightfull-screen sections

The root font size defaults to 16px, so 1rem is 16px and 1.5rem is 24px. Unlike em, rem never compounds through nesting, which is why it is the go-to unit.

100vh is exactly one screen tall, a favorite for hero sections, meaning the full-screen opening banner at the top of a landing page that holds the big headline and main button. The capstone builds one.

Text in rem, layout widths in % with a max-width, full-screen sections in vh, hairlines in px.

Converting rem to pixels

With the root font size at the default 16px, 2.5rem is 40px.

rem multiplies the root font size, so 2.5 × 16 = 40.

ValuePixels
1rem16
1.5rem24
2.5rem40

It does not care about the parent element's font size, only the root's, which is exactly what makes the arithmetic predictable anywhere in the document tree.

Converting a mockup to relative units

A designer hands over a mockup measured in pixels. A working stylesheet translates it with the rule of thumb above.

Mockup saysWritten asReason
h1 is 40pxfont-size: 2.5rem40 ÷ 16 = 2.5, and it scales with the base size
card padding 24pxpadding: 1.5remspacing tracks the text size
hairline divider 1pxborder: 1px solid graymust stay one device pixel
content column 960pxwidth: 90%; max-width: 60remfluid on phones, capped on monitors
full-screen intromin-height: 100vhone viewport tall on any device

The point of the conversion is that the numbers stop being frozen. A user who sets their browser font to 20px gets an h1 of 50px and padding of 30px automatically, and nothing overlaps.

The hairline is the instructive exception. A 1px divider expressed in rem would thicken to an ugly 1.25px at that same setting, for no benefit, so the fixed unit is the correct choice there.

How em compounds

A card at font-size: 20px with an inherited paragraph declaring padding: 1em gives the paragraph 20px of padding.

em multiplies the element's own font size, which here is the inherited 20px, so 1em is 20px.

DeclaredRelative toResult
1emthe inherited 20px20px
1remthe root 16px16px

That compounding through nesting is exactly what rem avoids, since 1rem would have been 16px regardless of the card. The compounding is occasionally useful, as in a button whose padding should grow with its label, and it is a liability everywhere else.

Two conversion helpers

The conversion runs both ways, and each direction is a single arithmetic operation.

function remToPx(rem, rootSize) {
  return rem * rootSize;
}

function pxToRem(px, rootSize) {
  return px / rootSize;
}

console.log(remToPx(1.5, 16));
console.log(remToPx(2.5, 16));
console.log(pxToRem(24, 16));

Output

24
40
1.5
DirectionOperation
rem to pxmultiply by the root size
px to remdivide by the root size

Passing rootSize in rather than hardcoding 16 keeps the helpers honest, because a project that changes the root size changes every conversion at once. That is the whole reason the unit is worth using.

The viewport height unit

The unit equal to 1% of the browser window's height is vh, for viewport height.

So height: 100vh fills the screen exactly, and vw does the same for width.

Unit1% of
vhthe viewport height
vwthe viewport width
%the parent element

The third row is the contrast that matters, since a percentage height depends on the parent and a vh height never does. On phones the address bar makes 100vh slightly taller than the visible area, which is why min-height is the safer property to pair it with.