CSS & layout
PX to REM converter
Pixels to rem and back, at whatever root font size your project uses.
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
| 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:
rem = px ÷ 16
px = rem × 16So 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:
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:
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.
Related tools
- PX to EM converter Pixels to em and back, plus the compounding behaviour that makes em bite.
- PX to Tailwind converter Turn a pixel value into the Tailwind utility that produces it, and find out when there isn't one.
- LiveMarkup Paste HTML, CSS and JS, see it render instantly. No account, no project setup, nothing to save.