Skip to main content
🎨 CSS as a design system·Module B4 · Lesson 2
TaskSet h1 to 2rem, h2 to 1.5rem, body to 1rem, .button padding to 0.5em 1em (em scales with button's font-size).

Sizing units: px vs em vs rem

75 XP6 min
Theory

Three units, three behaviors

.a { font-size: 16px; }     /* absolute — always 16 pixels */
.b { font-size: 1em; }      /* relative to PARENT's font-size */
.c { font-size: 1rem; }     /* relative to ROOT (<html>)'s font-size */

When to use each

  • `rem` — body text, headings, anything where you want predictable scaling tied to the user's preferred font size. Default unit in 2026.
  • `em` — when you want a property to scale with the LOCAL font-size. Classic: padding: 0.5em 1em on a button — the padding grows when the button text grows.
  • `px` — when you NEED a fixed value: borders (1px solid), shadows, sub-pixel adjustments.

Why rem won

The user can override the browser's default font-size in settings (a11y feature). Sites that use px everywhere ignore it. Sites that use rem automatically scale.

By default, 1rem = 16px. If the user bumps to 20px in their browser, every rem value in your CSS scales 25%.

:root { font-size: 100%; }      /* default — respects user setting */

NEVER do :root { font-size: 14px } to "make everything smaller" — you've just broken every user's a11y preference.

em compounds in nested elements

.parent { font-size: 1.2em; }     /* 1.2 × parent → 19.2px */
.parent .child { font-size: 1.2em; }   /* 1.2 × 19.2 → 23px (compounded!) */

Nested ems multiply. Use rem to keep sizes predictable.

🔒

Sign up to start coding

Theory is open to everyone. The interactive editor, live preview, and check are unlocked with a 7-day free trial — card required, cancel anytime.

Sign up — free trial →

First 15 lessons in each track are free. No card needed for those.

PreviousNext lesson →

Get one Python or web tip a day — by email

Short, hand-written, no spam. Unsubscribe in one click.