CSS units: px, rem, em
CSS units px, rem, and em define what a size value actually references: a fixed pixel, the parent font-size, or the root font-size.
Theory
TL;DR
pxis a brick: fixed size, unchanged regardless of parent or rootemis relative to the parent element's font-size and compounds on nestingremis relative to the roothtmlfont-size and stays consistent anywhere- Core problem with em: three levels of 1.2em = 1.728em (1.2³), not 1.2em
- Decision rule:
remfor almost everything,pxfor borders and shadows,emwhen padding should scale with the component's own font-size
Quick example
html { font-size: 16px; } /* rem base */
.parent { font-size: 2rem; } /* 32px */
.child-em { font-size: 1.5em; } /* 48px - multiplied by parent's 32px */
.child-rem { font-size: 1.5rem; } /* 24px - multiplied by root's 16px */
.child-px { font-size: 20px; } /* 20px - always 20px */.parent has 2rem (32px). Its child-em at 1.5em resolves to 48px, not 24px. rem ignores the parent entirely and reads the root.
Key difference
The reference point is everything. px has none - it is always the same number. em multiplies its parent's computed font-size, so deep nesting creates compound growth. rem always reads the html element's computed font-size, so 1.5rem is 24px whether the element sits at the top of the page or inside five nested components.
When to use
- Typography and spacing (most cases):
remscales with browser and OS font preferences - Borders, box-shadow, outlines:
pxkeeps edges crisp and does not benefit from scaling - Padding or margin proportional to component font-size:
em, likepadding: 0.75emon a button that grows and shrinks with its own text - Deeply nested menus or components:
removeremto avoid compound sizing math - 1px lines and small icons:
pxonly
Comparison table
| Aspect | px | em | rem |
|---|---|---|---|
| Reference | Fixed (1/96 inch) | Parent font-size | Root (html) font-size |
| Nesting effect | None | Compounds (1.2em x 1.2em = 1.44em) | Consistent |
| User zoom | Fixed | Scales with parent | Scales from root |
| Accessibility | Ignores font prefs | Tracks parent chain | Respects root prefs |
| Best for | Borders, shadows | Component-local ratios | Typography, spacing, layout |
How the browser handles this
Browsers resolve units during the cascade. html font-size is computed first (default 16px unless overridden). rem reads that root value directly. em walks up the style tree to find the parent's computed font-size, then multiplies. Both convert to absolute pixels before layout begins. px skips all of it.
Common mistakes
Using em for site-wide spacing
/* breaks in nested structures */
.menu { font-size: 1.2em; }
.menu li { font-size: 1.2em; } /* 1.44em already */
.menu li a { font-size: 1.2em; } /* 1.728em - unintended */
/* fix */
.menu li a { font-size: 1rem; }Three levels of 1.2em gives 1.728 times the base. That breaks layouts in ways that are hard to trace back.
Using px for body text
/* wrong: user font preferences are ignored */
body { font-size: 16px; }
/* right: scales with user and OS settings */
body { font-size: 1rem; }WCAG requires text to scale with user font preferences. px blocks that. It is an accessibility issue, not just a style preference.
Using em for borders
/* fine */
button { border: 1px solid #333; font-size: 1rem; }
/* looks off at large font sizes */
button { border: 0.1em solid #333; }Borders need a fixed, crisp edge. em on a border makes it thicker or thinner as the component font-size changes, which is rarely the intent.
Real-world usage
- Tailwind CSS:
p-4= 1rem, border classes usepx - Bootstrap 5:
$spacer: 1rembase, fixed elements inpx - Material-UI (MUI): theme typography with
h1: { fontSize: '2rem' } - Chakra UI: rem-based spacing tokens across the board
Follow-up questions
Q: What is the browser default root font-size?
A: 16px. Users can change it in browser settings. You can check the actual computed value with getComputedStyle(document.documentElement).fontSize.
Q: Does viewport meta affect rem?
A: Indirectly. width=device-width sets the logical pixel base on mobile. rem still resolves from html font-size, but the overall layout scales to fit the viewport.
Q: Why use px for box-shadow instead of rem?
A: Shadows in rem can look blurry at non-standard zoom levels. px keeps them sharp because shadow rendering happens at the pixel layer, not the font layer.
Q: In CSS-in-JS (Emotion, Styled Components), how do you handle rem with a dynamic root?
A: Read the root value at runtime with getComputedStyle(document.documentElement).fontSize, then convert px to rem programmatically. Most theme utilities in those libraries handle this automatically.
Q: Browser zoom scales px too. So what is the actual accessibility difference?
A: Browser zoom scales everything, including px. But OS-level font size settings (not zoom) only affect relative units like rem. A user who sets their system font to 20px benefits from rem, not from px.
Examples
em compounding breaks nested nav
:root { font-size: 16px; }
.nav { font-size: 1.125rem; } /* 18px */
.nav > li { font-size: 1.2em; } /* 21.6px */
.nav > li > a {
font-size: 1.1em; /* 23.76px - ballooned unintentionally */
padding: 0.5em; /* 11.88px - also unpredictable */
}
/* fix: use rem for inner elements */
.nav > li > a {
font-size: 1rem; /* 16px - predictable */
padding: 0.5rem; /* 8px - predictable */
}Two levels of em nesting pushed the font past 23px. Switching inner elements to rem keeps everything tied to the root, not to whoever sits above in the DOM tree.
rem-based button that respects user preferences
:root { font-size: 16px; }
.btn {
font-size: 1rem; /* 16px, scales with root */
padding: 0.75rem 1.5rem; /* 12px top/bottom, 24px sides */
border-radius: 4px; /* px - sharp corners */
border: 1px solid #333; /* px - crisp 1px line */
}If a user sets their browser base to 20px, the button font and padding scale automatically. The border stays at 1px, which is exactly right for a thin dividing line. I have seen codebases where everything was in px, and the team spent days debugging why accessibility users with large-font settings got a broken layout. Switching typography to rem fixed most of it in one line.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.