px to rem table
| px | rem (16px root) | rem (10px root, 62.5%) |
|---|---|---|
| 10px | 0.625rem | 1rem |
| 12px | 0.75rem | 1.2rem |
| 14px | 0.875rem | 1.4rem |
| 16px | 1rem | 1.6rem |
| 18px | 1.125rem | 1.8rem |
| 20px | 1.25rem | 2rem |
| 24px | 1.5rem | 2.4rem |
| 32px | 2rem | 3.2rem |
| 40px | 2.5rem | 4rem |
| 48px | 3rem | 4.8rem |
| 64px | 4rem | 6.4rem |
| 80px | 5rem | 8rem |
| 96px | 6rem | 9.6rem |
Converting in code
@use 'sass:math';
@function rem($px, $base: 16px) { @return math.div($px, $base) * 1rem; }
.card { padding: rem(24px); } // 1.5rem
// postcss.config.js
module.exports = {
plugins: { 'postcss-pxtorem': { rootValue: 16, propList: ['*'], minPixelValue: 2, mediaQuery: false } },
};
Want font sizes that grow with the screen? The clamp generator makes fluid sizes in rem. To tidy the converted stylesheet, use the CSS formatter.
Frequently asked questions
How do I convert px to rem?
Divide the pixel value by the root font size: rem = px ÷ root font size. With the browser default of 16px, 24px is 24 ÷ 16 = 1.5rem. To go back, multiply: 1.5rem × 16 = 24px.
Why use rem instead of px?
rem respects the user’s browser font-size setting. Someone who sets their default text size to 20px gets 1rem = 20px, so text and rem-based spacing grow with it, while px values stay fixed and can make text too small to read. Page zoom scales both px and rem, but the font-size setting only scales rem and em.
What’s the difference between rem and em?
rem is relative to the root element (html) font size, so 1.5rem is the same everywhere on the page. em is relative to the current element’s font size, so it compounds when elements are nested: 1.2em inside 1.2em is 1.44 times the root size. Use rem for most sizes, and em for things that should scale with their own text, like padding on a button or an icon next to a label.
Should I set html { font-size: 62.5% }?
It makes 1rem equal 10px (62.5% of 16px), so conversion is easy: 24px is 2.4rem. It still respects user settings because it’s a percentage. The catch is that any third-party component that assumes 1rem = 16px becomes smaller, and you need to set a readable body font size again. Set the root font size to 10 here to convert for that setup.
Why aren’t media queries converted by default?
In @media conditions, rem and em are always based on the browser’s initial font size (normally 16px), not on your html font-size. With a root size other than 16px, converting breakpoints with that root size would move them. With the default 16px root, converting is safe, and em or rem breakpoints then follow the user’s font-size setting.