Why Developers Should Switch from px to rem (And How to Do It Today)
A 2018 Internet Archive study found 3.08% of real users browse with a non-default font size — and px-based CSS silently overrides that choice. Here's why the switch to rem matters and how to do it in minutes.
Every front-end developer learns CSS with pixel units first. Pixels feel safe — 16px is 16px everywhere, the math is obvious, and design specs hand you pixel values directly from Figma or Sketch. So why change what works?
Here's the problem: in 2018, Evan Minto at the Internet Archive ran a real study measuring what browser font sizes their visitors actually had. The result — 3.08% of users were browsing with a non-default font size — sounds small until you do the math. On a site with 500,000 monthly visitors, that's over 15,000 people per month whose font preference your pixel-based stylesheet is silently overriding.
This post explains why that matters, what rem actually fixes, how Bootstrap and Tailwind have already made the decision for you, and the fastest way to convert an existing codebase — including a free px to rem converter online that handles bulk CSS in seconds without touching a command line.
Key Takeaways
- In 2018, the Internet Archive measured 3.08% of real users browsing with a non-default browser font size — a preference px units silently override (Evan Minto, Medium, 2018).
- WCAG 2.1 Success Criterion 1.4.4 (Level AA) recommends relative units over px for text — it's legally referenced by ADA, Section 508, and the EU's European Accessibility Act (effective June 2025).
- Bootstrap 5, Tailwind CSS, and Material UI all default to rem — the industry made this call years ago.
- Conversion takes one formula: rem = px ÷ 16. A free px to rem converter handles entire CSS files in one click.
What is actually wrong with using pixels in CSS?
Pixels are absolute units. 16px renders as 16px regardless of the operating system, the screen, or — critically — the user's browser font-size preference. When someone opens Chrome Settings, finds "Font size," and bumps it from Medium to Large, they're making an explicit accessibility choice. Rem units respect it. Pixel units don't.
The failure mode is subtle enough that most developers never notice it. Browser zoom (Ctrl/Cmd +) works fine with pixel units — it scales everything proportionally, including px values. So when you test at 150% zoom and everything looks correct, you think your site is accessible. What you didn't test is the separate browser font-size preference, found in Settings rather than the zoom shortcut. That preference only affects relative units. Pixels stay exactly where you put them.
In 2018, Evan Minto published data from the Internet Archive's Google Analytics on exactly this. They measured the actual default font size of their visitors by reading the computed root font size and undoing Bootstrap's 62.5% modifier. The finding: 3.08% of users had a non-default font size, with values ranging both larger and smaller than 16px (Evan Minto, "Pixels vs. Ems: Users DO Change Font Size," Medium, June 2018). These weren't bugs or misconfigured devices — they were deliberate user choices that px-based layouts ignored completely.
There's also a compliance angle. WCAG 2.1 Success Criterion 1.4.4 (Resize Text, Level AA) requires that text can be resized to 200% without loss of content or functionality. The W3C's own guidance for meeting this criterion explicitly recommends using relative units instead of fixed pixel values for font sizes (W3C, Understanding SC 1.4.4, WCAG 2.1). Level AA is the standard referenced in US ADA enforcement, Section 508, and the European Accessibility Act — which became enforceable for private-sector EU businesses in June 2025.
According to a 2018 Internet Archive study by Evan Minto, 3.08% of real users browsed with a non-default browser font size — a preference that pixel-based CSS overrides without warning. On a site with one million monthly visitors, that represents approximately 30,800 people per month whose explicit accessibility choice your stylesheet ignores. Switching to rem costs nothing and fixes the problem immediately (Evan Minto, Medium, 2018).
How does rem actually fix the problem px creates?
REM — Root EM — is relative to the font-size on the <html> element. All major browsers default that root to 16px. When a user sets their browser's preferred font size to 20px, the root becomes 20px, and every REM value in your stylesheet scales automatically. The user's choice is respected, not ignored.
Here's the same paragraph element written in both units:
/* px — ignores browser font size preference */
p {
font-size: 14px;
line-height: 21px;
margin-bottom: 16px;
}
/* rem — scales with user's root font size */
p {
font-size: 0.875rem;
line-height: 1.3125rem;
margin-bottom: 1rem;
}
On a screen with default settings, both look identical. The difference only appears when a user has changed their font preference — and that's exactly the case where it matters most.
A practical rule from developer educator Josh W. Comeau frames this clearly: ask yourself "should this value scale when a user increases their browser font size?" If yes, use rem. If no — a 1px border should stay 1px, a box shadow offset doesn't need to grow — use px. The answer is yes for almost every typographic and spacing value in your stylesheet (Josh W. Comeau, "The Surprising Truth About Pixels and Accessibility").
For a complete reference table of pixel-to-rem conversions at base 16px, see our px to rem conversion guide — it covers every common value from 1px to 100px.
Bootstrap, Tailwind, and Material UI have already switched to rem
The px vs rem debate was settled in major frameworks years ago. All three of the most widely used CSS frameworks default to rem, citing accessibility and user preference support as the primary reason:
Bootstrap 5 switched from px to rem in version 4 and cemented it in v5. Their documentation states the change was made to use "rems as much as possible to respect user font-size preferences." Tailwind CSS generates a 4-unit rem-based spacing scale (0.25rem, 0.5rem, 1rem, 1.5rem…) by default. Material UI uses rem throughout its theming system, with built-in support for custom base sizes.
The implication: if you're building on top of any of these frameworks, the components you pull in are already in rem. The only pixel values left in your codebase are the ones you're adding. Mixing px overrides into a rem-based framework undermines the consistency the framework was designed to provide.
There's a compound accessibility benefit that most developers overlook: rem-based media queries. When a user increases their browser font size, text takes more horizontal space — so available layout width effectively shrinks. A rem-based breakpoint responds to this correctly, showing the mobile layout when the user genuinely needs it. A pixel breakpoint fires at the same width regardless, potentially showing a two-column desktop layout to a user who enlarged their font specifically because the text was too small to read at desktop width.
What is the fastest way to convert an existing codebase from px to rem?
The conversion itself is straightforward — it's a single formula applied to every pixel value. How you apply it depends on the scale of your project.
Option 1 — Free px to rem converter online (fastest for ad-hoc work)
For a component stylesheet or a focused section of CSS, a browser-based converter is the fastest path. The ZerofyTools PX to REM Converter includes a Bulk CSS Replacer: paste any CSS block, set your base (default 16px), click Convert All, and every px value in the text is replaced with its rem equivalent. The output is ready to copy back into your file. Nothing is uploaded anywhere — it processes entirely in your browser.
Option 2 — PostCSS plugin (best for large projects)
For projects running a PostCSS build pipeline, postcss-pxtorem automates conversion at build time. You write pixel values in your source to match design specs exactly, and the plugin outputs rem in production. A basic config:
// postcss.config.js
module.exports = {
plugins: {
'postcss-pxtorem': {
rootValue: 16,
propList: ['font-size', 'line-height', 'margin', 'padding', 'gap'],
},
},
};
This is the right choice when your team receives pixel-value design specs and you don't want to add a manual conversion step to every handoff.
Option 3 — Manual conversion (small components)
For a focused component with 10–15 rules, manual conversion using the formula is faster than setting up tooling. Divide every pixel value by your root font size: rem = px ÷ 16. A component takes under 5 minutes. For the formula breakdown and a full reference table of common values, see the complete px to rem conversion guide.
When should you still use px instead of rem?
Not everything belongs in rem. Some values are deliberately absolute and should stay that way:
- 1px borders.
border: 1px solidshould stay as 1px. A 0.0625rem border rounds to nothing on some screens. Hairline borders are a visual detail, not a typographic one. - Box shadows. Offsets and blur radii like
box-shadow: 0 2px 8px rgba(0,0,0,0.15)are visual polish. They don't need to scale with font preferences. - Fixed-size canvas coordinates. If you're drawing to a
<canvas>element with explicit pixel dimensions, rem values don't apply. - outline-width hairlines. Same logic as borders — sub-pixel rendering makes rem impractical here.
The decision framework is simple: does this value relate to text or spacing that should breathe with the user's font preference? Use rem. Is it a decorative effect or a hairline that should stay sharp regardless? Use px. Most things — font-size, line-height, padding, margin, gap, max-width, media queries — belong in the rem column.
The ZerofyTools PX ↔ REM Converter handles individual values, bulk CSS files, and Tailwind scale exports — entirely in your browser. No file uploads, no installation.
Open the px to rem converter →Frequently Asked Questions
Why should I use rem instead of px in CSS?
REM units scale with the user's browser font-size preference, which 3.08% of real users actively change (Evan Minto, Internet Archive study, 2018). Pixel values ignore that preference entirely. On a site with 1 million monthly visitors, that's roughly 30,000 people per month whose accessibility choice px-based CSS silently overrides.
What is the fastest way to convert px to rem in CSS?
For individual files, a free px to rem converter online is the fastest path — paste a CSS block and every pixel value converts in one click. For large projects with a build pipeline, the postcss-pxtorem plugin automates it at compile time. The manual formula is: rem = px ÷ 16 at the browser default.
Is 1rem always equal to 16px?
Yes, in all major browsers (Chrome, Firefox, Safari, Edge) unless a custom html { font-size } rule is set. Some teams use the 62.5% technique — html { font-size: 62.5% } — to make the base 10px for easier math. The converter's Advanced Settings support any custom base from 8px to 64px.
Should CSS media queries use rem or px?
Rem. When a user increases their browser font size, text requires more horizontal space. A rem-based breakpoint fires at the right threshold because it responds to the root font-size change. @media (max-width: 48rem) equals 768px at default settings — and also fires correctly when the user has enlarged their font preference, which a px breakpoint never does.
When should I still use px instead of rem?
Use px for visual details that should never scale: 1px borders, box-shadow offsets, outline widths, and fixed-pixel canvas coordinates. The practical rule: if the value relates to text or spacing that should grow when a user enlarges their font preference, use rem. If it's a hairline or decorative shadow, use px.
The decision is already made for you
Bootstrap made the switch to rem years ago. Tailwind ships with rem by default. Material UI uses rem throughout. WCAG 2.1 AA — now legally enforceable across the EU, US federal sector, and beyond — recommends it for text sizing. And the 3.08% of your visitors who've chosen a larger font are counting on it.
The migration is mechanical. The formula is one operation. A free px to rem converter handles entire stylesheets in seconds. The case for px as a default unit for typography and spacing is increasingly hard to make — and the case for rem gets stronger every year accessibility compliance requirements tighten.
Start with your typography rules. Convert your spacing scale. Leave borders and shadows in pixels. Run the output through the visual preview to confirm nothing changed. That's the switch, done.
Sources:
Evan Minto, "Pixels vs. Ems: Users DO Change Font Size," Medium, June 2018, https://medium.com/@vamptvo/pixels-vs-ems-users-do-change-font-size-5cfb20831773
W3C, "Understanding SC 1.4.4: Resize Text," WCAG 2.1, retrieved 2026-05-19, https://www.w3.org/WAI/WCAG21/Understanding/resize-text.html
Josh W. Comeau, "The Surprising Truth About Pixels and Accessibility," retrieved 2026-05-19, https://www.joshwcomeau.com/css/surprising-truth-about-pixels-and-accessibility/
Every tool mentioned in this article runs entirely in your browser. Your files never leave your device.
Explore ZerofyTools →