Reference

CSS units.

Every CSS unit, grouped by what it's measured against. Tap any to copy it.

Tap any row to copy the value in the first column.

Absolute

UnitEqualsNotes
px1 CSS pixelThe everyday absolute unit
pt1/72 inchPrint; common in typography
in96pxInch — print
cm37.8pxCentimetre — print
mm3.78pxMillimetre — print

Font-relative

UnitRelative toNotes
emElement's font sizeCompounds when nested
remRoot (html) font sizeDoesn't compound — preferred
chWidth of the '0' glyphHandy for text column widths
exx-height of the fontRarely used

Viewport-relative

UnitRelative toNotes
vw1% of viewport widthResponsive widths
vh1% of viewport heightFull-height sections
vmin1% of the smaller sideSmallest viewport dimension
vmax1% of the larger sideLargest viewport dimension
%The parent / contextPercentage of the container

Grid, angle & time

UnitMeasuresNotes
frA fraction of free spaceCSS Grid track sizing
degDegreesRotations and gradients
turn1 full turn = 360degRotations
sSecondsAnimations and transitions
msMillisecondsAnimations and transitions

Absolute vs relative

CSS units split into two camps. Absolute units like px are fixed sizes — a pixel is a pixel regardless of context — which makes them predictable but unresponsive. Relative units are measured against something else, which is what makes layouts adapt. The two that matter most for type are em and rem: em is relative to the element's own font size and compounds when you nest elements, while rem is always relative to the root font size, so it stays predictable — which is why rem is the usual choice for scalable typography and spacing. For layout, the viewport units (vw, vh) size things against the screen, and fr distributes leftover space across CSS Grid tracks. A good default is rem for type and spacing, % or fr for layout widths, and px only where a fixed size is genuinely wanted, like a 1px border.

em vs rem, with the numbers

This is the distinction that causes the most confusion, and one worked example settles it. Assume the browser default root size of 16px.

rem is always measured against the root element, so 1rem is 16px anywhere in the document, no matter how deeply nested. em is measured against the current element's own font size, which means it compounds through nesting: a <div> at font-size: 1.5em renders at 24px, and a child inside it also set to 1.5em renders at 36px, not 24px. Nest a third and you are at 54px. That runaway growth in nested lists and menus is almost always an em problem.

The practical split most codebases settle on: rem for font sizes, so type scales predictably from one place, and em for padding, margins and border-radius on a component, so its spacing scales with its own text. A button with padding: 0.5em 1em keeps proportional padding whether it is a small button or a large one, with no extra rules.

Why px is an accessibility problem for type

Users can raise the default text size in their browser settings, and a meaningful number do. Sizes in rem and em respect that preference and scale up; a size in px does not, so text set in pixels stays small for someone who explicitly asked for larger text. Browser zoom scales everything either way, but the font-size preference only reaches relative units.

That is the argument for relative units on anything textual. Pixels remain entirely reasonable for things that should not scale with text — hairline borders, fine shadow offsets, a 1px rule.

You may also meet the 62.5% trick: setting html { font-size: 62.5% } makes 1rem equal 10px, so the mental arithmetic becomes trivial. It still honours the user's preference proportionally, but it does mean anything you forget to size explicitly inherits a small default, so use it deliberately rather than by habit.

Choosing a unit quickly

  • Font sizerem. Predictable, and it respects the user's text-size setting.
  • Padding and margin inside a componentem, so spacing tracks that component's text.
  • Borders and hairlinespx. These should not grow with text.
  • Full-viewport sectionsvh and vw, with the caveat that mobile browser chrome makes 100vh overshoot; dvh is the modern fix.
  • Widths inside a container%, measured against the parent.
  • Grid tracksfr, which splits whatever space is left over.
  • Line lengthch, roughly the width of a "0", which makes a max-width of about 65ch a good measure for readable prose.

FAQ

What's the difference between em and rem?
em is relative to the font size of the current element and compounds through nesting; rem is relative to the root (html) font size and doesn't compound. rem is usually preferred for consistent, scalable sizing.
When should I use rem instead of px?
Use rem for font sizes, padding and margins so everything scales if the user changes their base font size, improving accessibility. px is fine for things that shouldn't scale, like a hairline border.
Does em compound when elements are nested?
Yes, and that is the main reason people get caught out. With a 16px root, a div at 1.5em renders at 24px, and a child also set to 1.5em renders at 36px rather than 24px. rem never compounds, because it always measures against the root element.
Should I use px or rem for font size?
rem, in almost all cases. Users who raise the default text size in their browser settings get larger text with rem and em, but px ignores that preference entirely. Keep px for things that should not scale with text, such as hairline borders.
What is the 62.5% font-size trick?
Setting html { font-size: 62.5% } makes 1rem equal 10px on a default 16px root, so 1.4rem is 14px and the arithmetic becomes easy. It still scales with the user's preference, but anything you forget to size explicitly inherits a small default.

More references