This question comes up in almost every CSS code review: should this value be in px or rem? Both are valid, and the right answer depends on what the value is actually doing, not on a blanket rule.
How Each One Behaves
px is an absolute unit โ 16px is 16px no matter what. rem is relative to the root font size, which defaults to 16px in every major browser but can be changed by the user, or by your own CSS (some teams set html { font-size: 62.5%; } to make 1rem = 10px for easier mental math).
That one difference โ fixed vs. relative to a setting the user can control โ is what drives every recommendation below.
PX vs REM Side by Side
| px | rem | |
|---|---|---|
| Type of unit | Absolute | Relative to the root font size |
| Default size of 1 unit | 1 CSS pixel | 16px |
| Scales with browser zoom | Yes | Yes |
| Scales with the user's default font-size setting | No | Yes |
| Affected by nesting | No | No |
| Easy to read at a glance | Very | Needs a quick division by 16 |
Notice that both units scale with browser zoom. The difference only appears when someone changes their default font size in the browser settings, which is a separate control from zoom. Our article on how browser zoom affects rem and em explains why the two settings behave differently.
A Worked Example: A User With a 20px Default
Imagine a reader who has set their browser's default font size to 20px (the "Large" option in some browsers) because 16px text is hard for them to read. Here is what happens to the same card written two ways:
| Property | Written in px | Renders as | Written in rem | Renders as |
|---|---|---|---|---|
| Body text | 16px | 16px | 1rem | 20px |
| Heading | 24px | 24px | 1.5rem | 30px |
| Card padding | 24px | 24px | 1.5rem | 30px |
| Border | 1px | 1px | 1px | 1px |
The px version ignores the reader's preference completely. The rem version grows by 25% across text and spacing, while the border โ correctly left in px โ stays a crisp 1px line.
Where PX Still Makes Sense
- Borders โ
border: 1px solid #ccc;. A border doesn't need to scale with text size, and a fractional border can render inconsistently across browsers. - Box shadows and outlines โ offsets like
box-shadow: 0 2px 8px rgba(0,0,0,0.1)are about a fixed visual effect, not typography. - Media query breakpoints โ most teams still write
@media (max-width: 768px)because breakpoints are decisions about device width, not the user's font settings. - Icons and small fixed-size graphics โ a 24px icon usually should stay 24px regardless of font-size preferences.
Where REM Wins
- Font sizes โ if a visually impaired user bumps their browser's default font size up, rem-based text scales with that preference. Pixel-based text ignores it entirely.
- Spacing that should scale with type โ margin, padding, and line-height set in rem keep visual rhythm consistent when the base font size changes, instead of text growing while the surrounding whitespace stays frozen.
- Design systems and type scales โ most component libraries define spacing and typography scales in rem (0.5rem, 1rem, 1.5rem, 2rem) so the whole scale shifts together if the base ever changes.
A Simple Decision Rule
Ask: "should this get bigger if the user increases their font size?" If yes โ font-size, padding, margin, line-height โ use rem. If no โ borders, shadows, fixed-size icons, breakpoints โ use px. Most real projects end up using both side by side, and that's the correct outcome, not a compromise.
Quick Reference: Which Unit for Which Property
| Property | Recommended | Why |
|---|---|---|
font-size | rem | Respects the user's font-size setting |
padding, margin, gap | rem | Whitespace grows in step with text |
line-height | Unitless (e.g. 1.5) | Recalculated for each element's own size |
max-width of text blocks | rem or ch | Keeps line length readable when text grows |
border-width | px | Thin lines should stay thin |
box-shadow, outline-offset | px | Purely visual, not tied to reading |
border-radius | Either | px for a fixed look, rem if it should match padding |
| Media query breakpoints | px or em | Pick one convention project-wide |
Should You Use the 62.5% Trick?
Setting html { font-size: 62.5%; } makes 1rem equal 10px at the default, so 18px becomes 1.8rem without mental division. It still respects user settings because it is a percentage. The trade-offs: any third-party component that assumes 1rem = 16px will render at 62.5% of its intended size, and you must remember to set body { font-size: 1.6rem; }. Many teams now skip the trick and rely on a converter or a small preprocessor function instead:
// Sass helper: rem(24) โ 1.5rem
@use "sass:math";
@function rem($px, $base: 16) {
@return math.div($px, $base) * 1rem;
}
.title { font-size: rem(28); } // 1.75rem
Migrating an Existing PX Codebase
- Remove any px font size on
html. Replacehtml { font-size: 16px; }with100%or delete it, otherwise rem values will not respond to user settings either. - Convert font sizes first. They have the biggest accessibility impact. Divide each value by 16 โ 14px becomes 0.875rem, 18px becomes 1.125rem. Our step-by-step guide on how to convert PX to REM has a full table.
- Convert spacing next: padding, margin and gap values that sit around text.
- Leave borders, shadows and icon sizes in px.
- Test with a larger default font size. Set your browser to 20px or 24px and look for clipped buttons, overflowing navigation and fixed heights that no longer fit.
Common Mistakes
- Converting everything to rem, including 1px borders. A
0.0625remborder adds nothing and can render inconsistently when the root size is not a multiple of 16. - Fixed px heights on components with rem text. Text grows, the box does not, and content gets clipped. Use
min-heightand padding. - Assuming zoom testing is enough. Zoom scales px too, so it hides problems that only appear when the default font size changes.
- Mixing rem with em for font sizes without a clear reason. See our REM vs EM comparison for when em is the better pick.
Frequently Asked Questions
Does using rem hurt performance?
No. The browser resolves rem to pixels during style calculation, and there is no meaningful performance difference between the two units.
Is px bad for accessibility?
Not in itself. Px is fine for borders, shadows and decorative details. The accessibility problem is specifically px font sizes and text-related spacing, because they ignore the user's default font-size preference.
Why do some design tools only show px?
Design tools work on a fixed canvas, so px is a natural unit for them. Treat the px values as the design at a 16px root and convert them when you write CSS.
Can I use rem for media queries?
You can. Rem and em in media queries both refer to the browser's initial font size, so 48rem is 768px at the default. They do not follow a font size you set on html in your stylesheet.
Try It Yourself
Switching between the two by hand for a specific value? Our PX to REM converter does the conversion instantly, using either the default 16px root or a custom base you set, and the REM to PX converter works the other way.
