What is the difference between px, em, rem, %, vh, and vw in CSS?

px is absolute; em is relative to the parent font-size; rem is relative to the root font-size; % depends on context; vh/vw are percentages of the viewport.

CSS

Overview

Choosing the right CSS unit affects accessibility, responsiveness, and maintainability. Absolute units (px) are fixed regardless of context. Relative units (em, rem, %, vh, vw) scale based on something else - the parent, root, or viewport.

Key Points

  • β€’`px`: pixels - absolute, precise, unaffected by user font-size preferences (use sparingly).
  • β€’`em`: relative to the **current element's** font-size (or parent's if on font-size itself). Compounds when nested.
  • β€’`rem`: relative to the **root** (`<html>`) font-size - predictable, does not compound.
  • β€’`%`: relative to the parent's value for that property (width % β†’ parent width; font-size % β†’ parent font-size).
  • β€’`vh` / `vw`: percentage of the viewport height / width. `100vh` = full screen height.
  • β€’`ch`: width of the "0" character - great for sizing text containers.

Examples

px vs rem for font sizes

css
/* px: ignores user browser font-size settings */
.heading { font-size: 24px; }

/* rem: respects user preferences (root default is 16px) */
.heading { font-size: 1.5rem; } /* 1.5 Γ— 16px = 24px by default */

/* If user sets browser font to 20px, rem scales: 1.5 Γ— 20px = 30px */

Prefer rem for font-sizes so users who increase browser font size still benefit.

em compounds in nested elements (can be a trap)

css
.parent { font-size: 1.5em; } /* 1.5 Γ— 16px = 24px */
.child  { font-size: 1.5em; } /* 1.5 Γ— 24px = 36px - compounds! */

/* rem avoids this */
.parent { font-size: 1.5rem; } /* always 1.5 Γ— root (16px) = 24px */
.child  { font-size: 1.5rem; } /* still 24px, not compounded */

Viewport units for full-screen layouts

css
.hero {
  height: 100vh;  /* full viewport height */
  width: 100vw;   /* full viewport width */
}

/* svh (small viewport height) avoids mobile browser chrome overlap */
.hero { height: 100svh; }

ch for readable text width

css
/* Limit text to ~75 characters wide for readability */
.article-body {
  max-width: 65ch;
}

Practical guide: which unit to use

css
/* Font sizes       β†’ rem  */
/* Padding/margin   β†’ rem or em (em scales with local font-size) */
/* Borders          β†’ px   (you usually want crisp 1px borders) */
/* Width/height     β†’ % or fr (grid) or rem */
/* Full-screen      β†’ vh/vw or 100% */
/* Line-height      β†’ unitless (1.5) β†’ relative to own font-size */

Pro Tip

For accessibility, avoid defining font sizes in `px`. Users who increase their browser's default font size (a common accessibility need) will not see any change if you've hard-coded `px`. Use `rem` for font sizes.