Skip to content

CSS & layout

PX to REM converter

Pixels to rem and back, at whatever root font size your project uses.

px
rem
px
Click to copy.

rem is always relative to the root element's font size — the <html> element — no matter how deeply nested the element is. 16px is the browser default.

Reference table

Pixel values converted to rem
Pixels rem
1px 0.0625rem
2px 0.125rem
4px 0.25rem
6px 0.375rem
8px 0.5rem
10px 0.625rem
11px 0.6875rem
12px 0.75rem
13px 0.8125rem
14px 0.875rem
15px 0.9375rem
16px 1rem
18px 1.125rem
20px 1.25rem
22px 1.375rem
24px 1.5rem
26px 1.625rem
28px 1.75rem
30px 1.875rem
32px 2rem
36px 2.25rem
40px 2.5rem
44px 2.75rem
48px 3rem
56px 3.5rem
64px 4rem
72px 4.5rem
80px 5rem
96px 6rem
112px 7rem
128px 8rem
160px 10rem
192px 12rem
256px 16rem

Designs arrive in pixels and accessible CSS wants rem, so you end up doing the same small division about forty times a day. That’s all this is.

The rule

rem stands for “root em”. It’s always measured against the font size of the <html> element, however deeply nested the thing using it happens to be. The browser default is 16px, which gives you:

Text
rem = px ÷ 16
px  = rem × 16

So 16px is 1rem, 24px is 1.5rem, 8px is 0.5rem. There isn’t more to it than that.

Why bother when px is simpler

Someone who has bumped their browser’s default text size up gets nothing from a layout built in pixels. Their setting changes the root font size. Anything in rem moves with it, anything in px sits there ignoring them.

That’s the whole argument for it, and I think it’s enough on its own. It costs you one division and it means the site respects a preference somebody set deliberately, often because they need it.

Use rem for font sizes, spacing and container widths. Pixels are still right for things that genuinely shouldn’t scale: hairline borders, a 1px rule, the odd shadow offset.

The 62.5% trick, and where it bites

You’ll run into this one a lot:

CSS
html {
  font-size: 62.5%; /* 16 × 0.625 = 10px */
}

1rem is now 10px, 24px becomes 2.4rem, and the mental arithmetic goes away.

What people miss is that this changes the root size for everything on the page. Any third-party CSS that assumed 16px is now rendering at 62.5% scale. Embedded widgets, checkout iframes and plugin styles are the usual casualties, and it’s never obvious that your html rule is the cause.

The safer version puts the body back where it was:

CSS
html { font-size: 62.5%; }
body { font-size: 1.6rem; } /* back to 16px for actual text */

Set the basis field above to 10 if you work this way and the converter will follow.

Against em

rem looks at the root and never compounds. em looks at the parent and does, so three nested elements at 0.9em land you at 0.73 of where you started. The px to em converter covers that case properly.

Roughly: rem for layout, em for anything that ought to scale with its own context. Padding inside a button that should grow when the button’s text does is the classic example.

Two things that catch people out

Media queries ignore your html font size. Rems in a @media rule always resolve against the browser default, which is spec behaviour rather than a bug, and it means the 62.5% trick leaves your breakpoints exactly where they were. This surprises almost everyone the first time.

And you don’t need to convert a whole codebase in one pass. Do font sizes first, since that’s where the accessibility win actually lives. Spacing can wait until you’re next in that file anyway.

Published