Convert pixel values to REM units instantly. Set your base font size, then type any value.
| Pixels (px) | REM | Percentage (%) | Common use |
|---|
A PX to REM converter translates fixed pixel values into scalable REM units, making your CSS more accessible and easier to maintain. Pixels are absolute. REM is relative to the root font size, which means layouts built in REM scale gracefully when users change their browser's default font size.
This matters more than most developers expect. WCAG 2.1 success criterion 1.4.4 requires text to be resizable up to 200% without loss of content. Pixel-based font sizes can block that entirely.
The formula is straightforward:
| You have | Formula | Example |
|---|---|---|
| PX value | px ÷ base = rem | 24 ÷ 16 = 1.5rem |
| REM value | rem × base = px | 1.5 × 16 = 24px |
The base font size is whatever your root element uses. Browsers default to 16px, but many teams set it to 10px to make mental math easier (so 1rem = 10px).
font-size: 62.5% on your html element to get a 10px base without hardcoding pixels, keeping browser scaling intact.
The formula strip shows the exact calculation so you always understand the output, not just the number.
A PX to REM converter is a tool that calculates the REM equivalent of any pixel value based on a defined root font size. It can take the form of an online calculator, a Sass/SCSS function, a PostCSS plugin, or a VS Code extension.
The core formula is fixed: REM = PX ÷ Root Font Size. At the browser default of 16px, that means 24px becomes 1.5rem and 32px becomes 2rem.
Front-end developers, UI designers, and CSS authors use these tools daily when converting Figma design specs, building responsive typography systems, or migrating legacy pixel-based codebases to relative units.
The converter removes the mental overhead of constant manual division. That matters when you're handling 40+ spacing and font-size values in a single component.
Both units appear in almost every stylesheet. They do very different things.
|
Property |
PX |
REM |
|---|---|---|
|
Type |
Absolute |
Relative |
|
Reference point |
Fixed, device-independent |
HTML root element font size |
|
Scales with browser font settings |
No |
Yes |
|
Scales with browser zoom |
Yes |
Yes |
PX is an absolute unit. According to the W3C CSS specification, 1px equals 1/96th of an inch in CSS absolute terms. On screen, it renders as a device-independent pixel that stays fixed regardless of the user's browser font size preferences.
That fixedness is both its strength and its problem. Pixel-perfect layouts are predictable, but they break the moment a user with low vision increases their default browser font size.
REM is relative to the <html> element's font size. All major browsers - Chrome, Firefox, Safari, and Edge - default this to 16px, making 1rem equal to 16px out of the box.
Change html { font-size: 20px; } and every REM value across the entire site scales proportionally. That single declaration controls global font scaling, which is exactly why design systems prefer it.
One important thing: if a user sets their browser default font to 32px, each 1rem becomes 32px. REM respects that. PX ignores it entirely.
The formula has one variable: the root font size.
REM = PX ÷ Root Font Size
At the standard 16px root, the math looks like this:
8px ÷ 16 = 0.5rem
16px ÷ 16 = 1rem
24px ÷ 16 = 1.5rem
48px ÷ 16 = 3rem
Developers who set html { font-size: 10px } (or 62.5%) get a different result:
16px ÷ 10 = 1.6rem
24px ÷ 10 = 2.4rem
The 62.5% technique is popular because it makes the math easier - pixel values are simply divided by 10. But it has a real downside covered in section 6.
PX = REM × Root Font Size
So 1.5rem at a 16px base = 24px. At a 10px base = 15px. The base always matters, which is why every REM to PX converter asks for it upfront.
Reference table at the two most common root font sizes used in production codebases.
|
PX Value |
REM Value |
Common Use |
|---|---|---|
|
8px |
0.5rem |
Small spacing, icon padding |
|
12px |
0.75rem |
Captions, labels |
|
14px |
0.875rem |
Secondary body text |
|
16px |
1rem |
Base body font size |
|
18px |
1.125rem |
Comfortable reading size |
|
20px |
1.25rem |
Large body / small headings |
|
24px |
1.5rem |
H3-level headings |
|
32px |
2rem |
H2-level headings |
|
48px |
3rem |
H1-level headings |
|
64px |
4rem |
Display / hero text |
The same pixel values, different REM output:
16px = 1.6rem
24px = 2.4rem
32px = 3.2rem
48px = 4.8rem
These values match nothing in Tailwind CSS's spacing scale, which uses the 16px default. That's a common source of confusion when mixing the 62.5% approach with utility-first frameworks.
For quick lookups between other CSS measurement systems, converters like PX to EM, PX to PT, and PX to MM follow the same base-variable logic.
The accessibility argument is the strongest one. WCAG 2.1 Success Criterion 1.4.4 (Resize Text) requires text to scale to 200% of its size without loss of content or functionality. PX-based font sizes can fail this when users change browser font settings rather than using zoom.
Research from the Internet Archive found 3.08% of their users had changed their default browser font size - a number higher than the market share of browsers like Opera Mini or Edge at the time of measurement. That's not a negligible edge case.
WCAG 2.2, published as a W3C Recommendation in October 2023, builds on WCAG 2.1 and adds criteria focused on cognitive and low-vision users. Using PX for font sizes puts sites at risk against SC 1.4.4. Using REM avoids the issue entirely.
The W3C Web Accessibility Initiative (WAI) tutorials explicitly state: "The font size should be defined in relative units, such as percentages, em or rem. It is not possible to zoom text set in pixels independently from the rest of the page in some browsers."
73% of ADA website lawsuits in 2024 referenced WCAG 2.1 AA as the standard (UsableNet). Accessibility compliance is no longer theoretical.
Bootstrap 5, Tailwind CSS, Material UI, Foundation, and Bulma all use REM for font sizes and spacing by default.
Bootstrap 5 sets its root font size at 16px and uses rem throughout its typography and spacing scales. Tailwind's spacing scale - where p-4 equals 1rem (16px) - is built entirely on REM. Neither framework exposes pixel values to CSS directly for text sizing.
That's not an accident. REM enables global scaling with a single CSS property change, something pixel-based systems cannot replicate without touching every value individually.
Every REM value on a page is calculated relative to one thing: the font size set on the <html> element. Change that value and every REM-based measurement changes with it.
Default across all major browsers: 16px. This is set by the browser's User Agent stylesheet, not by any CSS reset or framework.
Many developers set html { font-size: 62.5%; } to make 1rem equal 10px. The appeal is obvious: 24px becomes 2.4rem, which is easier to calculate mentally than 1.5rem.
The cost is real though. From a CSS-Tricks accessibility audit: "My recommendation is to avoid setting font-size on the :root, <html> or <body> elements in favor of letting the browser's default size serve as a baseline."
Here's why: if you set html { font-size: 10px } using pixels instead of a percentage, you override the user's browser font preference entirely. A user who set their default to 20px now gets 10px as the root. That breaks the accessibility benefit of using REM in the first place.
The safer version: html { font-size: 62.5%; } uses a percentage, which scales relative to the user's browser setting. So if they've set 20px as their default, 62.5% of 20px = 12.5px as root. Still not 16px, but it respects the preference directionally.
All 4 major browsers default the root font size to 16px:
Chrome - 16px default, adjustable in Settings > Appearance > Font size
Firefox - 16px default, adjustable in Preferences > General > Fonts
Safari - 16px default, adjustable in Preferences > Advanced
Edge - 16px default, adjustable in Settings > Appearance
REM responds to these changes. PX does not. That's the entire argument in one sentence.
Manual conversion works fine for 10 values. It falls apart when you're working through a 200-property design token file or a component library being migrated from pixels.
3 methods developers actually use:
Define once, use everywhere. A Sass function removes manual division from the workflow entirely.
@function rem($px) {
@return ($px / 16px) * 1rem;
}
h2 {
font-size: rem(32px); // outputs 2rem
}
SitePoint and CSS-Tricks both document this pattern as the standard Sass approach. Chris Coyier's recommended variation keeps the root in PX, uses rem for module-level sizing, and uses EM for component-internal sizing - a three-tier system that's worth understanding if you're deep in a component architecture.
postcss-pxtorem converts PX to REM automatically at build time. You write pixel values in your CSS; the plugin outputs REM values in production.
Key configuration options:
rootValue - sets the base (default: 16)
propList - defines which CSS properties get converted (e.g., ['font-size', 'margin', 'padding'])
replace - if true, replaces the PX value; if false, adds REM as a fallback alongside PX
This approach works well in teams where designers export pixel values from Figma and developers want REM in output without a manual step. The EM to REM calculation is a related conversion some PostCSS configs also handle in the same pipeline.
calc() does not convert units. It cannot divide px to produce rem. This is a common misconception.
What calc() does well: combining REM with other units in a single value, like calc(1rem + 4px) for a border offset. For actual PX-to-REM conversion, use a preprocessor function or PostCSS, not calc().
Most developers reach for an online tool when they need a fast, one-off conversion or when they're working outside their usual IDE. The tools below are actually used in production workflows, not just listed for the sake of it.
|
Tool |
Type |
Key Feature |
|---|---|---|
|
nekoCalc |
Online calculator |
Custom root font size input |
|
cipchk PX to REM (VS Code) |
IDE extension |
Converts on keystroke in editor |
|
postcss-pxtorem |
Build tool plugin |
Automates conversion at compile time |
|
Bug0 CSS Unit Converter |
Online |
Converts PX, REM, EM, PT simultaneously |
nekoCalc lets you set a custom root font size before converting, which matters when your project doesn't use the 16px default. Most basic online converters assume 16px and don't tell you they're doing it.
The CM to PX and PT to PX converters follow the same structure for print-to-screen unit workflows, useful when adapting print design assets for web.
cipchk's "PX to REM" extension converts values inline as you type. It reads your project's root font size from config if set.
Took me longer than I'd like to admit to find this one. Once installed, it removes the context-switch of opening a browser tab mid-coding.
Chrome DevTools shows computed pixel values for every element but does not display REM equivalents natively. You get the final rendered size, not the authored REM value. For that, you'd need to inspect the CSS source directly or use a browser extension.
Figma outputs pixel values exclusively. Every spacing token, font size, and component dimension appears in pixels in the Inspect panel. The conversion to REM happens entirely on the developer side.
Developers at enterprise teams have noted this directly: "Our developers spend a lot of time in Figma Inspect, having to convert everything from pixels to REM." Atlassian addressed a related issue by implementing design tokens and structured documentation, which reportedly reduced visual bugs in their front-end by over 60% (Atlassian Design Engineering Report, 2023).
Tailwind's entire spacing and typography scale runs on REM at a 16px base.
text-base = 1rem (16px)
p-4 = 1rem padding (16px)
text-2xl = 1.5rem (24px)
Every utility class maps to a REM value. When you read Figma specs in PX and write Tailwind classes, you're doing implicit PX to REM conversion every time.
Bootstrap 5 switched from PX to REM starting with version 4. Its $font-size-base variable is set to 1rem, with all heading and spacing scales calculated from that root.
The $spacer variable defaults to 1rem, making mb-3 equal to 1rem of margin-bottom. Change $font-size-base and the entire spacing system scales.
Figma doesn't support REM natively. The Tokens Studio plugin for Figma lets teams define design tokens in REM-equivalent values and sync them to code. Without it, the conversion lives in a spreadsheet or a developer's head.
A Type Scale Generator helps bridge this gap by producing REM-based font size scales that can be used directly in design tokens and CSS custom properties.
Three units. One correct choice for most situations.
|
Unit |
Relative To |
Compounds in Nested Elements? |
Best For |
|---|---|---|---|
|
PX |
Nothing (absolute) |
No |
Borders, shadows, fixed icons |
|
REM |
HTML root element |
No |
Font sizes, spacing, layout |
|
EM |
Parent element font size |
Yes |
Component-scoped padding |
EM multiplies through nested elements. A parent with font-size: 1.5em containing a child also set to 1.5em produces 2.25× the root size, not 1.5×.
REM doesn't do this. 1.5rem is always 1.5× the root, regardless of nesting depth.
Setting button padding in EM means the padding scales proportionally when the button's font size changes.
padding: 0.5em 1em on a button with font-size: 1.125rem = 9px top/bottom, 18px left/right
Increase the font size and the padding grows with it
That's the EM use case. It's specific and intentional, not a default.
For reference on converting between these units directly, EM to PX and EM to REM converters handle the math when you're working across all 3.
REM for almost everything. PX for a short, specific list.
Use PX for:
border: 1px solid - borders should stay crisp and thin regardless of font scaling; a 0.0625rem border could render as 0 at small root sizes
box-shadow values - shadow dimensions that scale with font size look wrong; box-shadow: 0 2px 4px should stay 2px and 4px regardless of zoom
Fixed icon dimensions - a 24px icon grid (used in Material Icons and similar systems) needs to stay at exactly 24px to align with surrounding UI
outline on focus states - outline: 2px solid is a WCAG focus visibility requirement; keeping it in PX ensures predictable rendering
Never use PX for:
font-size on any text element
margin or padding in layout-level components
width or height on containers that should scale
The CSS-Tricks accessibility recommendation is direct: use REM and EM for everything except borders, where PX is appropriate. That's a good working rule.
REM is an accessibility unit. PX is not.
WCAG 2.1 Success Criterion 1.4.4 (Resize Text) requires content to scale to 200% without loss of function. Font sizes set in PX fail this criterion when users change browser font settings rather than using browser zoom. The W3C WAI tutorials state explicitly that it's not possible to zoom text set in pixels independently from the rest of the page in some browsers.
The numbers behind this are significant. According to the WebAIM Low Vision Survey, 36.7% of respondents with low vision use browser text sizing as a primary accessibility method. PX-based font sizes override that preference completely.
73% of ADA website lawsuits in 2024 cited WCAG 2.1 AA as the standard, according to UsableNet. Inaccessible font sizing is one of the most commonly flagged issues during accessibility audits (AdvancedBytez, 2023).
A user who sets their browser default font to 24px (1.5× the 16px standard):
font-size: 16px stays at 16px - the user's preference is ignored
font-size: 1rem becomes 24px - the user's preference is respected
That's the entire practical difference. One line of code, one decision, and a portion of your users either get the experience they configured or they don't.
Google's Lighthouse accessibility audit flags font sizes below 16px as a potential issue. It doesn't currently flag PX use directly, but AdvancedBytez notes that failing to scale text on 200% viewport zoom is one of the most common WCAG violations found during manual audits.
The color contrast checker addresses a related accessibility layer: readable text depends on both adequate size and sufficient contrast. REM handles the size side; contrast tools handle the other half.
Divide the pixel value by the root font size.
At the browser default of 16px: REM = PX ÷ 16.
So 24px becomes 1.5rem, 32px becomes 2rem. If your root font size differs, replace 16 with that value.
All major browsers - Chrome, Firefox, Safari, and Edge - set the default root font size to 16px.
This means 1rem equals 16px unless a developer or user changes the html element's font size.
REM scales with the user's browser font size settings. PX does not.
Users with low vision often increase their default browser font size. REM-based font sizes respect that preference; pixel-based sizes override it entirely, breaking accessibility.
Setting html { font-size: 62.5%; } makes 1rem equal 10px, simplifying the mental math.
Use a percentage, not html { font-size: 10px }. The pixel version overrides user browser preferences. The percentage version scales relative to them.
No. EM is relative to the parent element's font size and compounds through nested elements.
REM always refers to the root <html> element. 1.5rem is 1.5× the root everywhere, regardless of nesting depth. That predictability is why REM is preferred for layout and typography.
Use PX for borders, box shadows, and fixed icon dimensions.
A 1px solid border should stay thin regardless of font scaling. REM borders can produce inconsistent visual weight when users increase their browser font size.
Define a function once and call it throughout your stylesheet.
@function rem($px) {
@return ($px / 16px) * 1rem;
}
font-size: rem(24px) outputs 1.5rem. The function eliminates manual division across every property.
Figma outputs pixel values only in its Inspect panel.
The Tokens Studio plugin lets teams define design tokens in REM-equivalent values. Without it, developers handle the PX to REM conversion manually after every design handoff.
Yes. WCAG 2.1 Success Criterion 1.4.4 requires text to scale to 200% without loss of content or functionality.
Font sizes set in PX can fail this when users adjust browser font settings. REM-based font sizes pass automatically when the root is not locked with a pixel value.
Bootstrap 5, Tailwind CSS, Material UI, Foundation, and Bulma all use REM for font sizes and spacing.
Tailwind's p-4 equals 1rem. Bootstrap's $font-size-base is set to 1rem. Both frameworks treat PX to REM conversion as a solved problem at the framework level.