Problem Solved

CSS · rem vs em

Home › Courses › CSS › Problems › rem vs em
🎨 Concept · 3 min read

rem vs em.
Root-relative vs parent-relative.

1rem is always the same. 1em is different depending on where you are in the DOM. That's the whole difference — and it matters more than it sounds. This page covers why rem is the default for font sizes and spacing, when em is the right choice, and the compounding problem that makes em hard to predict in nested layouts.

Short answer: rem = root-relative. 1rem is always the root font size (usually 16px), regardless of where the element is. em = parent-relative. 1em is the parent's font size — so it changes with nesting. Use rem for font sizes, spacing, and layout — anything that should be consistent. Use em for component-relative sizing (button padding that scales with text). Never use px for font sizes — it breaks user preferences.

✅ Before and after

The same nested elements, with rem and em.

em-compounds.css
html {
font-size: 16px;
}

.parent {
font-size: 1.2em; /* 16 × 1.2 = 19.2px */
}

.child {
font-size: 1.2em; /* 19.2 × 1.2 = 23.04px */
}

.grandchild {
font-size: 1.2em; /* 23.04 × 1.2 = 27.648px */
}
Nesting depth vs font size:

Depth 0 (html): 16px
Depth 1 (.parent): 19.2px ← 1.2 × 16
Depth 2 (.child): 23.04px ← 1.2 × 19.2
Depth 3 (.grandchild): 27.65px ← 1.2 × 23.04

Each level multiplies by 1.2.

❌ The same CSS declaration produces
different font sizes depending on depth.
❌ "Why is my text getting bigger as I nest?"
❌ You have to know every ancestor's font size.

This is em compounding. It's not a bug —
it's how em works. But it's hard to predict.
rem-consistent.css
html {
font-size: 16px;
}

.parent {
font-size: 1.2rem; /* 16 × 1.2 = 19.2px */
}

.child {
font-size: 1.2rem; /* 16 × 1.2 = 19.2px */
}

.grandchild {
font-size: 1.2rem; /* 16 × 1.2 = 19.2px */
}
Nesting depth vs font size:

Depth 0 (html): 16px
Depth 1 (.parent): 19.2px
Depth 2 (.child): 19.2px
Depth 3 (.grandchild): 19.2px

Every level = 1.2rem = 1.2 × 16 = 19.2px.

✅ The same CSS declaration produces
the same size at every depth.
✅ Predictable — 1.2rem is 19.2px, always.
✅ Easy to reason about.
✅ Matches what designers expect.

This is why rem is the default unit for
font sizes and spacing.

✅ When em is the right choice

Component-relative sizing.

em-use-case.css
.button {
font-size: 1rem;
padding: 0.5em 1em; /* scales with font-size */
border-radius: 0.25em;
border: 1px solid currentColor;
}

.button--large {
font-size: 1.5rem;
/* padding and border-radius automatically scale
to 0.75rem 1.5rem and 0.375rem */
}

/* Icon size matching text */
.icon {
width: 1em;
height: 1em;
vertical-align: -0.125em;
}

/* Responsive padding based on viewport /
.container {
padding: 2em; / scales if font-size is changed /
}
Why em works for buttons:

Button default (font-size: 1rem):
padding: 0.5em 1em → 8px 16px
border-radius: 0.25em → 4px

Button large (font-size: 1.5rem):
padding: 0.5em 1em → 12px 24px ← automatically!
border-radius: 0.25em → 6px ← automatically!

✅ Change font-size, everything scales.
✅ One set of styles, multiple sizes.
✅ The padding is proportional to the text.

This is the correct use of em — component
styles that intentionally scale with font size.

If you used rem for the padding, the large
button would look cramped — the text would
be 1.5× but the padding would stay the same.

Rule: em for component-internal proportions,
rem for everything else.

Don't use em for font sizes in nested components. The compounding effect means a font-size: 1.2em on a deeply nested element can be 2× the size of the same declaration on a shallow one. This makes typography unpredictable — you set 1.2em, you get 23px in one place and 40px in another. Use rem for font sizes (consistent, root-relative, respects user settings), and reserve em for spacing inside a component (padding, border-radius) where you want the scaling. The rule of thumb: rem for layout, em for component internals.

⚠️ Common mistakes

The rem/em mistakes that cost real time.

1. Using em for font sizes everywhere

Compounds with nesting. Fix: rem for font sizes.

2. Assuming 1rem is always 16px

Depends on root font-size. Fix: check html { font-size } or user settings.

3. Using px for font sizes

Breaks user font-size preferences. Fix: rem.

4. Setting html { font-size: 62.5% }

Makes 1rem = 10px — but breaks user preferences and screen readers. Fix: leave html at default or 100%.

5. Mixing rem and em confusingly

Same project uses both without a rule. Fix: pick a convention (rem for layout, em for internals).

6. Using em for vertical margin

Compounds with nesting. Fix: rem for margin.

7. Forgetting line-height

Unitless line-height is relative to font size — works with rem or em. Fix: line-height: 1.5 (unitless).

8. Media query rem values

rem in media queries uses the root font size, not the user's font size. Fix: understand this before using rem breakpoints.

❓ Frequently asked

What is the difference between rem and em?

rem is relative to the root element's font size — usually html { font-size: 16px }. 1rem = 16px everywhere, regardless of nesting. em is relative to the parent element's font size — 1em is the current font size of the parent, which could be anything. This is the key difference: rem is consistent across the page, em compounds with nesting.

Why does em compound?

Because em is relative to the parent's font size, which is relative to its parent, which is relative to its parent — all the way up to the root. If body is font-size: 16px, and a div is font-size: 1.2em (19.2px), and a child is font-size: 1.2em (23.04px), and a grandchild is 1.2em (27.648px), each level multiplies. This is often called 'the em cascade' or 'em compounding.'

When should I use rem?

Use rem for anything that should be consistent across the page: font sizes, spacing (padding, margin, gap), widths and heights, border-radius, box-shadow offsets. If you set html { font-size: 16px }, then 1rem = 16px, 2rem = 32px, everywhere. rem also respects user accessibility settings: if the user changes their browser's default font size, rem scales with it.

When should I use em?

Use em when a size should scale with the parent's font size. Classic use cases: (1) Button padding — if the button font-size is 1rem, padding: 0.5em 1em gives 8px × 16px padding; if the font is 1.5rem, padding scales to 12px × 24px. (2) Border-radius that stays proportional to text. (3) Icon sizes that should match adjacent text. em is the right tool when the design intentionally couples two sizes.

Is 1rem always 16px?

No — 1rem is always equal to the root element's font size, which is usually 16px but can be anything. If you set html { font-size: 62.5% }, then 1rem = 10px. If you set html { font-size: 20px }, then 1rem = 20px. The default in most browsers is 16px, but users can change it in their browser settings — this is a feature, not a bug.

Should I use rem, em, or px?

Use rem for font sizes, spacing, and most layout dimensions. Use px only for things that should never scale: hairlines (1px borders), very fine details. Use em for component-relative sizing (button padding that scales with font, icon sizes that match text). Never use px for font sizes — it breaks user font-size preferences.

🔗 Related

← All CSS problems
Problem solved · CSS