px, rem, em and % — which CSS unit to use where

rem scales with the reader's font size, px does not, and em compounds when you nest it. The differences are small until an accessibility audit, so here is the rule for each one.

What each unit is measured against

The CSS Unit Converter converts between all of these, and its base field is the root font size the conversion assumes — 16 by default, because that is the default in every major browser.

The accessibility difference, stated precisely

This is the part most explanations get slightly wrong. A reader who sets their browser's default font size to 20px is telling every site to start from 20px. Type sized in rem follows that. Type sized in px ignores it completely and stays exactly as you specified.

Page zoom is different: zoom scales px along with everything else, so a px-based layout is not unusable — it simply overrides a preference the reader already expressed, and forces them to zoom the entire page when all they wanted was larger text.

That is the whole argument for rem on anything text-sized. It is not about pixel-perfection; it is about not discarding a setting the user deliberately changed.

Where em is the right answer

Use em when something should scale with nearby text rather than with the document. Padding inside a button, the gap between an icon and its label, a border-radius that should stay proportional to a label — all of these read better in em, because bumping the button's font-size carries them along automatically.

The failure mode is nesting. Give <li> a font-size: 0.9em and a list three levels deep is at 0.73em without anyone deciding that. Type scales belong in rem for exactly this reason.

The 62.5% trick, and its one catch

Setting html { font-size: 62.5%; } makes 1rem equal 10px on a default browser, so 1.4rem reads as 14px and the mental arithmetic disappears. Because 62.5% is relative to the reader's default rather than a fixed 10px, it still honours their preference — it is a legitimate technique, not a hack that breaks accessibility.

The catch is that every third-party stylesheet on the page now computes rem against 10px too, and component libraries generally assume 16. Set the base to 10 in the converter to model this before committing to it.

The media-query gotcha

Inside a media query, em and rem both resolve against the initial font size — the browser default or the user's preference — never against whatever you set on <html>. So the 62.5% trick does not shift your breakpoints, and @media (min-width: 40em) means 640px for a default reader and 800px for someone running a 20px default. That is usually what you want, and it is always surprising the first time.

A working default

Tools used in this guide