Why the Pixel vs. Rem Debate Misses the Point

The question of whether to use pixels or relative units like em and rem for sizing carries more emotional weight than most CSS decisions. Conflicting advice is everywhere: some argue that rem is essential for accessibility, while others claim that modern browsers have made pixel-based layouts a non-issue. The reality is that the most accessible product requires both.

How Each Unit Actually Behaves

px is the most direct unit in CSS, conceptually equal to one dot on the screen. It's the least abstract and often feels intuitive for sizing because there's no hidden math involved.

.box {
  width: 1000px;
  margin-top: 32px;
  padding: 8px;
}

An em is different: it's a ratio relative to the element's calculated font size. If a paragraph has a bottom margin of 1.5em, that margin is 1.5 times the paragraph's font size. This anchoring lets values scale proportionally with the text they surround.

That same relativity is what makes em tricky. Font size is inherited, and em compounds through the DOM tree. Consider a nested structure where each level applies a different em-based font size: the final computed size must be calculated by multiplying each ratio along the way, cascading from the root down until a fixed value is found.

<style>
  main {
    font-size: 1.125em;
  }
  article {
    font-size: 0.9em;
  }
  p.intro {
    font-size: 1.25em;
  }
</style>

<main>
  <article>
    <p class="intro">
      What size is this text?
    </p>
  </article>
</main>

In that example, a paragraph inside a chain of multiple em-sized parents ends up with a computed size you can't just eyeball without doing the multiplication 16 × 1.125 × 0.9 × 1.25, which yields 20.25 pixels. Manageable for a simple chain, but it gets unwieldy fast in complex layouts.

The rem unit, which stands for Root EM, was introduced to sidestep this issue. It behaves like em, but it always calculates against the font size of the root element, the <html> node. Inherited font sizes are ignored entirely, making the math predictable. By default, 1rem is 16px, because browsers start with a 16px base. That base is not fixed, however; it's configurable by the user at the browser level.

Where Accessibility Comes In

The primary accessibility concern in this sizing conversation is vision. People with low vision need reliable ways to enlarge text, and there are two main paths to do so. One is browser zoom, typically triggered with a keyboard shortcut. The other is changing the browser's default font size in its settings, which redefines the baseline that relative units like em and rem build from: users who set their default to 32px are effectively redefining 1rem globally.

This second behavior is where the problem with pixels appears. When a font-size is specified in pixels, it's impervious to the user's chosen default font size. Only relative units like rem will respond to this setting. For this reason, using relative units for text is recommended—it merely means honoring the user's customization.

Browser zoom offers a partial mitigation. It scales everything: pixels, ems, rems, everything except viewport units. So users can always zoom to get larger text, even on pixel-based sites. But zoom is site-by-site. A user with poor vision shouldn't have to manually adjust zoom per website; ideally, they can set a global default that every site respects. There's also a matter of motor ability. Keyboard shortcuts and zoom controls aren't universally reachable; users relying on dictation or eye tracking may find them impractical. Giving users as much control as possible without blocking those settings is the ideal.

When it comes to typography, relative units are almost always the safer choice—but that logic doesn't apply universally to every measurement in CSS, and that’s exactly why a rigid "rems only" policy is wrong.The decision about which unit to use should be driven by the context of the measurement: text should generally be flexible, but other aspects of the interface may depend on proximity to fixed layout boundaries. Balancing that requires the use of both types of units.

Choosing units deliberately

Given that rem responds to both zoom and font scaling, the temptation is to use it everywhere. But rem has a side effect: everything set in rem grows with the user's default text size. That's desirable for typography, but it isn't always desirable for spacing, sizing, or layout constraints.

Consider horizontal padding. When text size increases, fewer characters fit per line. If padding also grows in rem, the usable line width shrinks further, compounding the readability problem. Border widths suffer from the same logic: a border doesn't need to thicken just because the user prefers larger text.

The strategic question to ask for every value is straightforward:

Should this value scale up as the user increases their browser's default font size?

If yes, use rem. If no, use px. The correct answer isn't always obvious, so it helps to work through concrete cases.

Media queries and available space

/* Should we do this: */
@media (min-width: 800px) {
}

/* …Or this: */
@media (min-width: 50rem) {
}

The distinction matters because rem-based breakpoints shift with the default font size. If a user doubles their default text size to 32px, then 50rem evaluates to 1600px instead of 800px. With px-based media queries, the breakpoint stays at 800px regardless of font settings.

At first glance, sliding the breakpoint up seems wrong: a desktop user with large text would get the mobile layout. But that's actually the desired outcome in many cases. Think of media queries less in terms of device categories and more in terms of available space. A user who increases their default font size has reduced the amount of content that fits in a given viewport. The same optimizations that serve a mobile user now serve them better.

A real-world example illustrates the point. On a course platform with a left-hand sidebar for navigation and content on the right, the sidebar is often set to a rem-based width so that long lesson titles don't wrap when text size increases. With a pixel-based media query, that wider sidebar consumes most of the viewport on smaller laptops. With a rem-based media query, the layout switches to the mobile, toggleable-navigation view, giving content the space it needs to remain readable.

For this reason, rem is the better choice for media queries. Users who scale up their default font size will see the mobile layout on desktop, which is generally preferable to a cramped desktop layout with oversized text.

Vertical margins and text spacing

Vertical margins between paragraphs serve a functional purpose: they make it easy to see where one paragraph ends and the next begins. In horizontally written languages, this spacing is part of the reading experience, not just decoration.

Because these margins support readability, scaling them with the user's root font size makes sense. As text grows, the visual separation between paragraphs should also grow to remain effective.

Widths and heights

Fixed-width elements present a genuine trade-off. Take a button with a set width. Its font-size should clearly be in rem, but the width is less obvious:

  • A pixel-based width keeps the button from growing with the font size, which can force text onto multiple lines and make the button taller.
  • A rem-based width scales the button wider in proportion to the text, preserving its aspect ratio.

In most cases, rem is the better choice, since multi-line buttons look awkward. But there are exceptions: if vertical space is scarce and horizontal space is plentiful, or if a specific layout calls for a fixed width, pixels may be appropriate.

Testing your assumptions

When the right unit isn't clear, the best way to decide is to test. Set the browser's default font size to 32px or 48px and view the design with both px and rem values. Compare which version produces more readable content and a better overall experience.

For those unfamiliar with changing the default font size, the major browsers have documentation on how to do it:

With repeated testing, the right choice becomes second nature.

Beyond rules: building intuition

A list of rules — "use pixels for X, use rems for Y" — is easy to memorize but hard to apply in practice. Real layout challenges are messy and don't always fit clean categories. Even experienced developers run into novel situations.

The more useful approach is to develop a mental model of how CSS actually works. When the underlying principles are clear, the right answer follows without needing to recall a rule. This is why many developers find CSS frustrating: a patchy understanding makes the language feel unpredictable and brittle. A solid foundation flips that experience, making CSS enjoyable to work with.

This philosophy extends beyond units. Interactive demos and hands-on experimentation beat rote memorization for building genuine fluency. The same way that testing layouts with scaled font sizes sharpens your unit-choice instincts, exploring how CSS properties interact in practice builds the deeper intuition that makes the language feel reliable. For those who want to go further, a comprehensive course like CSS for JavaScript Developers applies this approach to the full CSS language, covering core concepts and real-world projects for developers using component-based frameworks.

Making rem Work For You

When accessibility requirements demand that text scale with user preferences, rem is often the right tool. But it comes with a cost: the mental math required to convert pixel values into rems is tedious, and it produces unwieldy decimals for almost every size except 16px. Before resorting to memorization, consider these approaches that simplify the workflow.

The 62.5% shortcut and why to avoid it

A widely circulated trick is to alter the root font size so that 1rem equals 10px instead of the default 16px:

html {
  font-size: 62.5%;
}

p {
  /* Equivalent to 18px */
  font-size: 1.8rem;
}
h3 {
  /* Equivalent to 21px */
  font-size: 2.1rem;
}

With this setup, conversion is a simple matter of moving a decimal point: 18px becomes 1.8rem rather than 1.125rem. The math becomes trivially easy.

Despite its popularity, this approach has significant downsides. It assumes that 1rem produces readable text—a baseline assumption that many third-party components, browser extensions, and injected HTML rely on. Setting the root to 62.5% shrinks that assumption by nearly 40%, breaking tooltip libraries and user-injected content that use rem-based sizing. Migration is also a hurdle: adopting this half-way creates inconsistent rem definitions across the codebase, and convincing a team to rewrite every existing declaration is a logistical challenge. The long-term cost is rarely worth the cleaner math.

Calculated conversions

For those who want explicit pixel values in their stylesheets while outputting rems, the CSS calc() function can handle the division automatically:

p {
  /* Produces 1.125rem. Equivalent to 18px */
  font-size: calc(18rem / 16);
}
h3 {
  /* Produces 1.3125rem. Equivalent to 21px */
  font-size: calc(21rem / 16);
}
h2 {
  /* Produces 1.5rem. Equivalent to 24px */
  font-size: calc(24rem / 16);
}
h1 {
  /* Produces 2rem. Equivalent to 32px */
  font-size: calc(32rem / 16);
}

This method keeps the math honest and readable in the declaration itself. The downside is verbosity—every rem usage requires typing out the full calc() expression, which becomes noisy across a large stylesheet.

Storing conversions as CSS variables

A cleaner approach is to do the conversion once and store the results in CSS custom properties:

html {
  --14px: 0.875rem;
  --15px: 0.9375rem;
  --16px: 1rem;
  --17px: 1.0625rem;
  --18px: 1.125rem;
  --19px: 1.1875rem;
  --20px: 1.25rem;
  --21px: 1.3125rem;
}

h1 {
  font-size: var(--21px);
}

Naming variables numerically (for example, --font-size-18) might look unconventional, but it is spec-compliant and works in all modern browsers. Once defined, consuming these values is nearly as easy as typing a raw pixel value, but with full accessibility benefits. The same pattern applies to spacing scales in a design system:

html {
  --font-size-xs: 0.75rem;
  --font-size-sm: 0.875rem;
  --font-size-md: 1rem;
  --font-size-lg: 1.125rem;
  --font-size-xl: 1.3125rem;
  --font-size-2xl: 1.5rem;
  --font-size-3xl: 2.625rem;
  --font-size-4xl: 4rem;
}

None of these techniques are strictly superior; the goal is to make the process manageable without sacrificing the user experience. As long as a user can scale every piece of text on the page, the implementation details are secondary.