Quick Answer

px is an absolute, fixed size. em is relative to the font size of its parent element, so it can compound when elements nest inside each other. rem is relative to the root (html) font size, so it stays predictable no matter how deeply you nest. For most work, use rem for font sizes and spacing, em when something should scale with its own text, and keep px only for tiny fixed details like 1px borders.

What CSS units actually do

Every time you write font-size: 16px or padding: 2em in CSS, you are choosing a unit — the part that tells the browser how big something should be. The three you will meet most often are px, em, and rem. Picking the right one affects how readable your text is, how cleanly your layout scales, and whether people who need larger text can actually get it.

This guide breaks down em vs rem vs px in plain language, with examples you can paste and run. By the end you will know exactly which unit to reach for in typography, spacing, and media queries. If you want to practise these ideas in a real project, our free CSS course walks through them step by step.

px: the absolute unit

px (pixels) is an absolute unit. When you say 16px, you get 16 pixels — a fixed size that does not change based on any parent or root setting.

.box {
  font-size: 16px;
  padding: 24px;
  border: 1px solid #ccc;
}

The upside is that px is predictable. What you write is what you get, with no maths in your head. That makes it great for small, precise details: a 1px border, a thin divider, or a subtle box-shadow offset.

The downside is that px is rigid. If a user raises their browser's default font-size setting because they find small text hard to read, elements sized purely in px do not grow with that preference. For body text and layout that should adapt, this is a real accessibility limitation — which is exactly where relative units come in.

em: relative to the parent (and it compounds)

em is a relative unit. When used for font-size, it is measured against the font size of the parent element. So 1em equals the parent's font size, 1.5em is one and a half times it, and 0.5em is half.

.parent {
  font-size: 20px;
}
.child {
  font-size: 1.5em;  /* 1.5 × 20px = 30px */
}

Because em looks at the parent, it can compound (stack up) when elements nest inside each other. Watch what happens with a nested list:

ul {
  font-size: 0.8em;
}
<ul>          <!-- 0.8em of the body -->
  <li>Level 1
    <ul>      <!-- 0.8 × 0.8 = 0.64em -->
      <li>Level 2
        <ul>  <!-- 0.8 × 0.8 × 0.8 = 0.512em -->
          <li>Level 3 — now tiny!</li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

Each level multiplies the one above it, so deeply nested text shrinks (or grows) unexpectedly. That compounding is em's biggest gotcha — but it is also its superpower when you want a whole component to scale from a single font size, as we will see.

rem: relative to the root (no compounding)

rem stands for "root em". It is also relative, but it always measures against one thing: the font size of the root element, which is <html>. It ignores parents entirely, so it never compounds.

html {
  font-size: 16px;   /* the root */
}
.parent {
  font-size: 20px;
}
.child {
  font-size: 1.5rem; /* 1.5 × 16px = 24px, NOT 30px */
}

Notice that .child ignores its parent's 20px and uses the root's 16px instead. No matter how deeply you nest elements, 1.5rem is always the same size. That predictability is why rem has become the default choice for most modern CSS.

A handy trick: since the browser default root size is usually 16px, 1rem = 16px, 1.5rem = 24px, and 2rem = 32px. To convert, just divide the pixel value you want by 16 to get the rem value.

Why rem helps accessibility and scaling

Here is the key reason rem matters beyond tidy code: accessibility. Browsers let users change their default font size (in Chrome: Settings → Appearance → Font size). Many people with low vision rely on this.

When your text and spacing are in rem, they are all tied to that root size. Bump the root from 16px to 20px and everything scales together — proportionally and predictably. With px, nothing responds to that setting.

There is one rule that makes this work: do not lock the root font size in px.

/* Avoid: this overrides the user's preferred size */
html { font-size: 16px; }

/* Better: leave html alone so it defaults to the user's setting,
   then size everything else in rem */

/* Or scale relative to the user's choice */
html { font-size: 100%; }  /* = the user's default, usually 16px */

Leave the root alone (or use 100%), size your text and layout in rem, and your site respects each visitor's choice for free. To build a fully accessible layout from scratch, the Priodemy CSS course covers this hands-on.

px vs em vs rem at a glance

Questionpxemrem
Relative unit?NoYesYes
Based on…Fixed pixelsParent / own font sizeRoot (html) font size
Can compound when nested?NoYesNo
Scales with user's font setting?NoYesYes
Predictable at any depth?YesPartialYes
Best for1px borders, fine detailScaling within a componentTypography, spacing, layout

A rule of thumb for typography, spacing, and media queries

Here is a simple, practical rule you can follow on almost any project:

  • Typography (font-size): use rem. Text stays predictable and honours the user's font setting. Example: font-size: 1.125rem; for body text (18px).
  • Spacing (padding, margin, gap): use rem as your default for consistent rhythm across the page. Reach for em when you want spacing to scale with the element's own text — button padding is the classic case.
  • Media queries (breakpoints): use em. Breakpoints in em respond to zoom reliably and behave consistently across browsers.
  • Fine details: keep px for hairline borders (1px), small shadows, and anything that should never scale.

The button example makes em's value obvious:

.button {
  font-size: 1rem;
  padding: 0.75em 1.5em;  /* padding grows with the button's text */
}
.button.large {
  font-size: 1.5rem;      /* padding scales up automatically */
}

Because the padding is in em, making the button's font bigger also enlarges its padding — the whole button stays perfectly proportioned with a single change.

Common gotchas to watch for

1. em compounding sneaks up on you

If several nested elements all use em for font-size, the sizes multiply and text drifts from what you expected. When in doubt for typography, use rem.

2. em on font-size behaves differently from em elsewhere

For font-size, em is based on the parent's font size. For other properties like padding or width, em is based on the element's own font size. This surprises many beginners.

.card {
  font-size: 20px;
  padding: 1em;   /* 1 × 20px = 20px (uses its OWN font-size) */
}

3. A px root font size hurts accessibility

As covered above, a px root font size stops users from scaling text with their browser preference. Leave <html> at the default or use 100%.

4. rem is not "better" everywhere

rem is the safe default, but em is genuinely the better tool when you want a component to scale from one font size. Use the right unit, not just the popular one.

The bottom line

You do not need to overthink this. A reliable default that works for nearly every project looks like this:

  • Do not set a px font-size on <html> — let the user's default stand.
  • Use rem for font sizes, and for most padding, margins, and gaps.
  • Use em when something should scale with its own text (buttons, badges, icons next to text).
  • Use em for media-query breakpoints.
  • Keep px for 1px borders and tiny fixed details.

In one line: rem by default, em when you want things to scale together, px for the hairlines. Follow that and your layouts will be predictable, proportional, and accessible.

Ready to put it into practice? Work through real exercises in the free Priodemy CSS course and build layouts that scale cleanly on every screen.

Frequently Asked Questions

Is rem always better than px?

No. rem is the better default for typography, spacing, and layout because it scales with the user's font setting and never compounds. But px is still the right choice for details that should stay fixed, like a 1px border or a small shadow. Use each where it fits.

Why does text using em get smaller in nested lists?

Because em multiplies. If a ul is set to 0.8em, a list nested inside it becomes 0.8 × 0.8 = 0.64em, and a third level 0.512em. Each level compounds on the one above. Switch that font-size to rem to keep every level the same size.

Should I use em or rem for media queries?

Use em. In media queries both em and rem are based on the browser's default font size, but em is the widely recommended choice because it responds to zoom reliably and avoids older browser quirks. For example, at the default 16px, min-width: 40em equals 640px.

What is 1rem in pixels?

By default, 1rem equals 16px, because that is the browser's default root font size. So 1.5rem is 24px and 2rem is 32px. To convert any pixel value to rem, divide it by 16 — for example, 18px ÷ 16 = 1.125rem.

Does using px for font sizes hurt accessibility?

It can. If you size the root or body text in px, users who raise their browser's default font size will not see your text grow, which makes reading harder for people with low vision. Sizing text in rem lets it honour that preference automatically.