Why rem Beats px for Font Sizing (And When It Doesn't)

The advice to 'always use rem' gets repeated a lot without explanation. Here's what's actually different.

If you've spent any time writing CSS, you've probably seen advice telling you to use rem instead of px for font sizes, and you may have followed that advice without fully understanding why. It's one of those rules that gets repeated so often it starts to feel like dogma rather than a reasoned decision — so let's actually work through what's different, where it matters, and where the difference is genuinely irrelevant.

What a pixel actually is on the web

A CSS pixel isn't the same thing as a physical pixel on your screen. On a high-density "Retina" display, one CSS pixel might correspond to four or more physical pixels. That abstraction already tells you something: CSS pixels were never meant to be a precise physical measurement, they're a consistent logical unit that the browser translates to whatever the actual screen needs.

When you write font-size: 16px, you're telling the browser "make this text exactly 16 of these logical units tall, no matter what." That word "exactly" is the whole story. It's a fixed, absolute value that doesn't respond to anything else on the page or in the user's settings.

What rem actually does differently

rem stands for "root em" — it's a unit that's always relative to the font size set on the root <html> element. By default, most browsers set that root size to 16px, so 1rem and 16px often look identical when you first test them. That similarity is exactly what makes the difference easy to overlook — the two units behave identically until something changes the baseline, and then they diverge sharply.

The thing that changes the baseline, in practice, is almost always a user's own accessibility settings. Someone with low vision can go into their browser or operating system settings and increase the default font size — maybe to 20px, maybe higher. If your whole site is built in rem, every single measurement that depends on font size scales up proportionally and the layout keeps working. If your site is built in px, none of it moves. The user's accessibility setting is silently ignored, and text that was already hard for them to read stays exactly as small as you originally set it.

This isn't a hypothetical edge case

It's tempting to file this under "edge case, probably fine to ignore," but browser accessibility settings aren't obscure. Every major browser exposes a font-size preference, and a meaningful share of users — particularly older users, or anyone with any degree of visual impairment — actually uses it. If your button labels, form placeholders, and paragraph text are all hard-coded in px, you've built a site that actively works against the one accessibility lever those users have available to them.

There's a second, quieter benefit too. If you ever decide your whole site's type scale feels slightly too small or too large, changing the root font-size in one place adjusts everything built in rem proportionally. With px, you'd be hunting through every stylesheet rule individually.

Where px is still the right choice

None of this means px is always wrong. For properties where you genuinely want a fixed, unchanging measurement regardless of font size — a 1px hairline border, a specific icon's width and height, a fixed-size loading spinner — px is exactly right, because you don't want that measurement to shift just because someone bumped their browser's text size. The rule of thumb that actually holds up: use rem for anything related to typography or spacing that should feel proportional to the reading experience, and use px for anything that's a fixed structural or decorative measurement independent of text size.

A note on em, the other relative unit

em is relative too, but relative to the current element's own font size rather than the root's. That sounds similar to rem but behaves very differently in nested elements, since each level of nesting can compound the multiplication. A padding value set in em inside a component whose font size itself was set in em can produce sizes that are hard to predict just by reading the CSS. rem sidesteps that entirely by always anchoring to one single root value, which is why it's generally the safer default for most typography and spacing work, with em reserved for cases where you specifically want a measurement to scale with its own immediate parent rather than the page root.

Converting between the two

If you're working from a design file that specifies everything in pixels — which is extremely common, since most design tools default to px — the conversion to rem is simple as long as your root font size is the standard 16px: divide the pixel value by 16. An 18px heading becomes 1.125rem, a 24px heading becomes 1.5rem, and so on. If you'd rather not do that math by hand for every value in a design spec, our CSS unit converter handles the conversion between px, rem, em, and percent instantly, and our typography scale generator can build out a full proportional heading scale in rem from a single base size if you're setting up a new type system from scratch.

The short version

Use rem for font sizes and most spacing so your site respects a user's own accessibility preferences and stays easy to adjust globally. Use px for fixed, structural measurements that genuinely shouldn't scale with text size. It's a small habit to build, and once it's automatic you stop having to think about it — which is really the point of good defaults in general.