DevKitHub

Programming

PX to REM Converter — rem, em, pt and Every CSS Unit

Enter a length such as 24px or 1.5rem to see it in every CSS unit at your root font size, or paste CSS to rewrite each px value as rem. Media queries and hairline borders are left alone unless you ask.

24px at a 16px root

px
24px
remroot
1.5rem
emparent
1.5em
%of parent font
150%
pt
18pt
pc
1.5pc
in
0.25in
cm
0.635cm
mm
6.35mm
Q
25.4Q
vwof viewport
1.25vw
vhof viewport
2.2222vh
ch≈ 0.5em
3ch
ex≈ 0.5em
3ex

Convert a stylesheet

16 lines
16 lines

Stylesheet

Converted
8 px values to rem
  • 1 px value in @media was left alone. In a media query, rem and em are relative to the browser’s default font size, not to html { font-size }, so dividing by your root would move the breakpoint. Choose “em at 16px” to convert them correctly.
  • 1 value of 1px or less was kept in px, so hairline borders stay one pixel wide. Turn off “Keep 1px” to convert them too.

Common sizes at a 16px root

Pixel sizes and their rem equivalents
pxrem
1px0.0625rem
2px0.125rem
4px0.25rem
6px0.375rem
8px0.5rem
10px0.625rem
12px0.75rem
13px0.8125rem
14px0.875rem
15px0.9375rem
16px1rem
18px1.125rem
20px1.25rem
22px1.375rem
24px1.5rem
28px1.75rem
32px2rem
36px2.25rem
40px2.5rem
44px2.75rem
48px3rem
56px3.5rem
64px4rem
72px4.5rem
80px5rem
96px6rem
128px8rem

This tool runs entirely in your browser. Your input is never uploaded, stored or logged.

How it works

rem is the font-size of the root element, 16px unless the page or the reader changes it, so px to rem is a division: 24px at a 16px root is 1.5rem, and at a 10px root it is 2.4rem. em is the font-size the element itself has, which is the one it inherits unless it sets its own, and in the font-size property em and % both refer to the parent. The absolute units are fixed ratios in CSS Values 4: 1in is 96px and 2.54cm, 1pt is 1/72in, 1pc is 12pt and 1Q is a quarter of a millimetre. Worked as fractions, 12pt is exactly 16px rather than 15.999999999999998. vw and vh are percentages of the viewport size you give, and ch and ex use the 0.5em that the specification assumes when a font’s metrics are unknown, which real fonts only approximate. Results are rounded to four decimal places by default, which at a 16px root is accurate to under a thousandth of a pixel; two places turns 13px into 0.81rem, which is 12.96px.

The reason to use rem at all is the browser’s default font-size setting. Page zoom scales px and rem alike, and is how most sites meet WCAG 1.4.4 Resize Text, but some readers enlarge the default text size instead, because it makes text bigger without making the whole layout bigger. A font-size in px ignores that setting; one in rem follows it. The 62.5% trick sets html { font-size: 62.5% } so that 1rem is 10px and the arithmetic is easy. It still follows the reader’s setting, but any text that is not given its own size renders at 10px until body is reset, and a third-party component whose styles assume a 16px rem shrinks to 62.5% of its intended size.

The stylesheet converter reads CSS with a tokeniser that follows CSS Syntax Level 3, so only numbers with a px unit in declaration values are changed: px inside a string, a url(), a comment, a selector or an at-rule prelude is left exactly as written, and so is 0px. Values of 1px or less are kept by default: a hairline is usually meant to stay one, and border widths are snapped down to whole device pixels, so converting one gains little. Media queries are left in px unless you choose otherwise, because Media Queries Level 4 evaluates em and rem in a query against the browser’s initial font size, never against html { font-size }. Converted with a 10px root, 768px would become 76.8rem, which the browser reads as 1228.8px; postcss-pxtorem’s mediaQuery option does exactly that. Here the em option always divides by 16 and writes em, whatever the root.

Common problems

Every example below is run against this tool in our test suite, so what it says here is what the tool actually does.

CSS numbers use a dot for the decimal point, never a comma: write 1.5rem, not 1,5rem.

1,5rem
Why:
In locales that write decimals with a comma the habit carries into CSS, where a comma separates values, so 1,5rem is not one length and the browser drops the whole declaration.
Fix:
Use a dot for the decimal point: 1.5rem.

dp is an Android density-independent pixel, not a CSS unit. Material and Flutter treat one dp as one CSS px on the web, so use px.

16dp
Why:
Design handoffs for Android and Flutter give sizes in dp and text in sp. CSS has neither unit, and a browser drops any declaration that uses one.
Fix:
Read dp as px, then convert to rem. Treat sp as rem, since both follow the reader’s text-size setting.

This converts a single length. A calc(), min(), max() or clamp() expression mixes units that are only resolved by the browser.

clamp(1rem, 2.5vw, 2rem)
Why:
A math function has no single value in px until layout: 2.5vw depends on the viewport and the clamp on which bound wins, so there is nothing to convert it to.
Fix:
Paste the whole declaration into the stylesheet converter, which rewrites the px values inside calc() and clamp() and leaves the rest.

A 768px breakpoint converted at a 10px root now triggers at 1228px.

Why:
em and rem in a media query are relative to the browser’s initial font size, not to html { font-size: 62.5% }, so 76.8rem is 76.8 × 16px there. Some build plugins convert media queries with the root value anyway.
Fix:
Leave breakpoints in px, which this converter does by default, or choose “em at 16px”, which turns 768px into 48em whatever the root.

A 1px border stayed 1px after converting.

Why:
Values of 1px or less are kept on purpose. Border widths are snapped down to whole device pixels, so 0.0625rem renders as a single pixel at most text sizes, and most designs mean a hairline to stay one.
Fix:
Turn off “Keep 1px” if you do want hairlines to scale with the text.

Frequently asked questions

How do I convert px to rem?
Divide by the root font size, which is 16px unless html { font-size } changes it: 24px ÷ 16 = 1.5rem, and 14px ÷ 16 = 0.875rem. To go back, multiply: 1.5rem × 16 = 24px. With html { font-size: 62.5% } the root is 10px, so 24px is 2.4rem.
Should media queries use px, em or rem?
By Media Queries Level 4, em and rem in a query both mean the browser’s initial font size, not the root font-size your stylesheet sets, so they behave the same. A breakpoint in em moves when the reader raises their default text size, which keeps the layout from cramming large text into a narrow column; one in px does not. Either way, convert at 16px: 768px is 48em.
Why is 1pt 1.333px?
CSS fixes 1in at 96px and a point at 1/72 of an inch, so 1pt is 96/72 = 4/3 of a pixel. That is why 12pt text is 16px, and why a point size copied from a print design comes out a third larger in px.
Does rem make my site accessible?
It removes one obstacle. Font sizes in rem follow the browser’s default text-size setting, which font sizes in px override. Page zoom enlarges both, so px text can still meet WCAG 1.4.4 Resize Text, but readers who change the default size rather than zooming get nothing from px.

Last updated