
px to rem: The CSS Unit Conversion That Actually Matters for Accessibility
📷 Boskampi / Pexelspx to rem: The CSS Unit Conversion That Actually Matters for Accessibility
Most CSS developers still write pixel values by hand. Here is why switching to rem units makes your layouts more accessible, easier to maintain, and how to convert between them without the mental math.
Something I noticed when I started doing code reviews on front-end projects: nearly everyone writes pixel values for font sizes and spacing, even developers who know perfectly well that rem exists. It is not ignorance — most of them can explain what rem is. They just default to pixels because that is what they learned first and because the mental math of dividing by 16 every time adds just enough friction to keep them in pixel-land.
The problem is that pixels are not quite as "real" as they feel. Modern CSS pixels are not physical screen pixels. They are reference pixels defined by the CSS specification, and more importantly, they are fixed — they do not respect the user's browser font size preference. That fixedness has consequences that only show up when someone with different needs tries to use your site.
What rem Actually Means
rem stands for "root em." It is a relative unit that is always calculated against the font size set on the root element of the document — the <html> element.
The browser default for that root size is 16px. So by default:
1rem= 16px1.5rem= 24px0.875rem= 14px2rem= 32px
The conversion formula is simple: rem = px ÷ base font size. To go the other direction: px = rem × base font size.
The base font size used in most conversions is 16px, because that is the browser default. But if you have set a different root font size in your CSS — which some style guides do — you need to use that number instead.
em Is Not the Same Thing
Before going further: rem and em look similar but they are meaningfully different, and confusing them leads to cascading headaches.
em is relative to the current element's font size, or in some properties, to the parent element's font size. This sounds flexible, but it compounds. If you set a container to font-size: 0.8em and put a child inside it with font-size: 0.8em, the child renders at 0.8 × 0.8 = 0.64em relative to the root — smaller than you might expect.
rem always goes back to the same reference point: the <html> element. No compounding. No surprises based on where the element sits in the tree. You write 1.5rem and it means 1.5 × the root font size, full stop.
For most typography and layout work, rem is the right choice. em is still useful for things that genuinely should scale relative to the current element — button padding that scales with the button's own font size, for instance — but as a default, rem is much easier to reason about.
Using the Pixel-REM Converter
The Pixel-REM Converter on ToolBox Hub handles the arithmetic so you do not have to.
You enter a pixel value, the tool shows the equivalent rem and em values. You can also go the other direction: enter a rem value and see the pixel equivalent. The base font size defaults to 16px, matching browser defaults, but you can change it — if your project sets html { font-size: 18px }, put 18 in the base size field and all conversions will be accurate for your specific setup.
The tool also includes a conversion table that shows common pixel values (8, 10, 12, 14, 16, 18, 20, 24, 32, 48, 64, 96) alongside their rem equivalents at the base size you have specified. This is the part I find most useful for day-to-day work — I keep it open in a browser tab while working through a design spec, and I can scan the table instead of calculating each value individually.
Step by Step
- Enter your pixel value — type the number you want to convert (no need to add "px").
- Check or change the base font size — default is 16. Change this if your project uses a non-standard root font size.
- Read the rem value — the result updates instantly.
- Scan the conversion table — see common sizes at a glance for the base size you entered.
That is genuinely all there is to it. The tool exists to eliminate the micro-friction that causes developers to default to pixels.
The Accessibility Argument
Here is the core reason to care about this beyond code elegance: some users change their browser's default font size.
This is more common than most developers assume. People with low vision frequently set their browser default to 20px, 24px, or even larger. Older users, people using devices at arm's length, people who simply prefer larger text — they all have legitimate reasons to have adjusted this setting.
When you use px for font sizes, that preference is silently ignored. The browser can not scale your fixed-pixel text to match what the user asked for. The text stays the same size regardless of their setting.
When you use rem, the math works out the way it should. A user with a 20px root font size will see your 1rem text at 20px. Your 1.5rem heading renders at 30px instead of 24px. The whole layout scales proportionally, which is usually exactly what the user wanted when they increased their browser font size.
This is not an edge case. The Web Content Accessibility Guidelines explicitly address this: Success Criterion 1.4.4 (Resize text) requires that text can be resized up to 200% without loss of functionality, and browser-level font scaling is one of the intended mechanisms. Pixel-based font sizes fail this criterion in many implementations.
There is also a subtler benefit: if a user has a preference set and your site is the only one that ignores it, your site looks broken or out of place compared to everything else. Small thing, but it adds up to an impression.
The Common Counterarguments
"I can just use browser zoom instead of font size scaling." Browser zoom scales everything — text, images, layout — which is different from a user who specifically wants larger text without changing the overall layout scale. They are not the same control.
"We test at 16px so it does not matter for our users." You do not know what your users have set. Analytics do not show browser font size preferences. The users most affected by pixel-based fonts are also the users least likely to be captured in your tracking data.
"rem makes the codebase harder to read." There is something to this. font-size: 1.25rem is less immediately readable than font-size: 20px. This is why having a conversion table open (or using the converter) helps — you can look up the pixel value whenever you need a gut-check. Some teams solve this with CSS custom properties: --font-size-lg: 1.25rem; /* 20px */ with the pixel equivalent noted in a comment.
"I use a design system that already specifies pixel values." The conversion tools exist for exactly this: your design spec says 24px, you run it through the converter, you write 1.5rem. The design values stay in the spec; the implemented values use proper units.
How Different Projects Handle the Base Size
There are a few common approaches to the root font size:
Leave the default (16px). Most common. No CSS change required. Conversions are just ÷16. The downsides are that 16 is an awkward divisor for mental math and the resulting rem values have more decimal places (14px = 0.875rem).
Set to 62.5% (10px equivalent). html { font-size: 62.5%; }. This makes 1rem = 10px, so 14px = 1.4rem, 24px = 2.4rem. The math is friendlier. The trade-off is that you need to explicitly set font-size: 1.6rem (or similar) on the body to restore readable default text, since browsers default body text to 1rem which would now render at 10px. Easy to forget that step.
Set to 100% (16px) explicitly. html { font-size: 100%; }. Functionally the same as leaving the default, but explicit in the CSS. Some teams prefer the clarity. Still ÷16.
Custom value. Some design systems use an 8-point grid and set the root to 8px, making all grid-aligned values use round numbers. Others match their design tool's default. Whatever you choose, set it in the converter tool so your conversions are accurate.
Practical Workflow Tips
Convert as you build, not after. It is much easier to write 1.5rem while implementing a component than to go back afterward and audit all pixel values for replacement. The converter takes about one second per value.
Use custom properties to document the relationship. In your CSS or design tokens file:
:root {
--text-sm: 0.875rem; /* 14px */
--text-base: 1rem; /* 16px */
--text-lg: 1.125rem; /* 18px */
--text-xl: 1.25rem; /* 20px */
--text-2xl: 1.5rem; /* 24px */
}
The comment keeps the pixel reference visible for anyone reading the code while the actual value is in rem.
Keep pixels for things that genuinely should not scale. Borders, box shadows, some decorative elements — these often look fine at a fixed pixel size regardless of font scaling. Not everything needs to be in rem. The places where it matters most are font sizes, line heights, and the spacing values that affect text readability (margins around paragraphs, padding inside text containers).
Test with a different browser font size. Temporarily go to your browser's font size setting, set it to 20px or 24px, and browse your own site. If your layout breaks or text overlaps, that is the problem the rem unit is designed to solve. This test takes 30 seconds and shows you what some of your users see every day.
The em Use Cases Worth Knowing
Even if rem is the default, em has legitimate uses.
Button padding. If a button has font-size: 0.875rem and padding of 0.5em 1em, the padding is calculated against the button's own font size. If you later need a larger version of the button with a bigger font, the padding scales automatically. This is intentional and correct behavior.
Icon sizing. An icon that should always be the same visual size as adjacent text can be set to width: 1em; height: 1em and it will match the line height naturally regardless of what size the text around it is.
Within-component scaling. Sometimes you have a component with a set font size where all internal spacing should be proportional to that component's font, not the root. em makes this relationship explicit.
The key is that em is for intentional relative relationships within a component. rem is for everything that should relate back to the user's global font preference.
Related Tools
CSS Units Converter — Converts between a wider range of CSS units including vh, vw, vmin, vmax, pt, and pc, not just px/rem/em. Useful for viewport-relative unit conversions.
CSS Box Shadow Generator — When building component styles that include box shadows, this tool generates the CSS. Box shadow values are one place where pixels are still the norm and appropriate.
Color Converter — Convert between hex, RGB, HSL, and other color formats while building your design system. Often needed alongside unit conversions when working through design specs.
FAQ
What is the difference between px, rem, and em in CSS? px is fixed and ignores browser font settings. rem is relative to the root element's font size (typically 16px by default). em is relative to the current element's or parent element's font size and compounds when nested. For most use cases, rem is the most predictable choice.
How do I convert px to rem? Divide the pixel value by the base font size. Default base is 16px, so 24px ÷ 16 = 1.5rem. The Pixel-REM Converter does this instantly and lets you set a custom base size if your project uses a non-standard root font size.
Why use rem instead of px for font sizes? Users can increase their browser's default font size for accessibility reasons. px-based fonts ignore this preference. rem-based fonts scale correctly with user settings, making your site accessible to people who rely on browser font scaling.
Does using rem break my layouts? Not if you approach it gradually. Start by converting font sizes and the spacing values that directly affect text. Fixed pixel values are still appropriate for borders, dividers, and decorative elements. The conversion is additive — you do not have to convert everything at once.
What is the html { font-size: 62.5% } trick?
It sets the root font size to 10px (62.5% of 16px), making rem values more human-readable: 14px = 1.4rem, 24px = 2.4rem. The catch is you must set an explicit font size on the body, otherwise text renders at 10px. Many teams use it, but it adds a gotcha for developers who join later without context.
Final Thoughts
The px-to-rem conversion is a small change with disproportionate accessibility benefits. It is also the kind of thing that is easy to understand conceptually but tedious enough to apply in practice that most projects never fully commit to it. Having a conversion tool open while working genuinely changes the friction calculation.
The Pixel-REM Converter is there for exactly that moment when you are implementing a design spec and you have a pixel value that needs to become a rem value. No mental math, no calculator app, just a quick tab switch and the right number.