Skip to content
ZeroServer.tools
All guides

CSS Units Explained: px, rem, em, vw, vh, and When to Use Each

June 10, 2026 · 6 min read

CSS Units Explained: px, rem, em, vw, vh, and When to Use Each

CSS has over a dozen length units, and using the wrong one in the wrong context causes brittle layouts, accessibility failures, and mobile display bugs. The good news: once you understand the categories and the tradeoffs, the rules become intuitive.

Absolute Units

Absolute units map to a fixed physical or logical size, regardless of anything else on the page.

px (pixels) — The most familiar unit. In CSS, 1px is not necessarily one device pixel — on a retina display, 1px might map to 2 or 3 physical pixels. What px really means is a single CSS pixel, defined by the W3C as 1/96th of an inch at arm's length. For practical purposes: px gives you predictable, fixed sizes.

border: 1px solid #e2e8f0;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);

pt (points) — 1pt = 1/72 inch. Comes from print typography. Avoid on screens — it has no meaningful advantage over px for digital output and creates confusion.

cm, mm, in — Literal centimeters, millimeters, inches. Only relevant for print stylesheets (@media print). On screen, 1in = 96px regardless of the monitor's actual DPI.

Relative Font Units

These units scale relative to font sizes, making them powerful for responsive and accessible typography.

em — Relative to the parent element's font-size. This is where it gets dangerous: em values compound through nested elements.

body { font-size: 16px; }

.parent {
  font-size: 1.25em;  /* 16 * 1.25 = 20px */
}

.parent .child {
  font-size: 1.25em;  /* 20 * 1.25 = 25px — NOT 20px! */
}

This compounding ("em cascade") is the most common CSS pitfall for developers learning relative units. Use em for spacing that should scale with the local text size (padding, margins inside a component), but avoid it for font-size unless you're explicitly controlling the cascade.

rem (root em) — Relative to the root element's (<html>) font-size. No compounding, ever. The default browser root font-size is 16px, so 1rem = 16px unless overridden.

:root { font-size: 16px; }  /* 1rem = 16px everywhere */

h1 { font-size: 2rem; }     /* 32px */
p  { font-size: 1rem; }     /* 16px */
small { font-size: 0.875rem; } /* 14px */

rem is the preferred unit for font sizes and most layout spacing because it respects the user's browser font preference. If a user sets their browser default to 20px (common for accessibility needs), your entire layout scales proportionally. px font sizes bypass this preference entirely.

ch — Width of the 0 (zero) character in the current font. Useful for controlling text line length:

.prose { max-width: 65ch; }  /* ~65 characters per line — readable measure */

ex — Height of the lowercase x in the current font. Rarely used in practice.

Viewport Units

Viewport units are relative to the browser's viewport size, making them ideal for full-screen layouts.

vw (viewport width) — 1vw = 1% of the viewport width. 100vw = full viewport width.

vh (viewport height) — 1vh = 1% of the viewport height. 100vh = full viewport height.

/* Full-screen hero section */
.hero {
  width: 100vw;
  height: 100vh;
}

The mobile 100vh problem: On mobile browsers, 100vh includes the address bar height — so the page overflows behind the browser chrome. This caused layout issues for years. The fix is the new dynamic viewport units.

svh (small viewport height) — The viewport height when the browser chrome (address bar, nav) is fully visible. Smallest possible viewport.

lvh (large viewport height) — The viewport height when the browser chrome is hidden (user scrolled down). Largest possible viewport.

dvh (dynamic viewport height) — Dynamically updates as the browser chrome shows/hides. The correct choice for full-screen mobile layouts:

.hero {
  /* Fallback for older browsers */
  height: 100vh;
  /* Correct on modern mobile */
  height: 100dvh;
}

vmin / vmaxvmin is the smaller of vw and vh; vmax is the larger. Useful for responsive sizing that adapts to orientation.

Container Query Units

New in 2023, now baseline across all modern browsers:

cqw (container query width) — 1% of the containing element's width (requires container-type on the parent). cqh — 1% of the containing element's height.

.card-container {
  container-type: inline-size;
}

.card-title {
  font-size: clamp(1rem, 4cqw, 1.5rem);  /* scales with card width */
}

Container units enable truly component-scoped responsive design, independent of the viewport.

When to Use What

Property Recommended Unit Why
font-size rem Scales with user browser preference
Spacing (padding, margin) rem or em rem for consistent scale; em for component-relative spacing
border, outline, box-shadow px Fine details should be crisp and fixed
Full-screen height dvh (+ vh fallback) Avoids mobile browser chrome issues
Full-width layout vw or % Relative to viewport or parent
Text line length ch Directly tied to character count
Responsive font scaling clamp() with vw Smooth scaling between breakpoints
Print stylesheets pt, cm, mm Physical measurements only

Fluid Typography with clamp()

clamp(min, preferred, max) is the modern way to scale typography smoothly between viewport sizes without media query breakpoints:

h1 {
  font-size: clamp(1.75rem, 4vw, 3rem);
  /* At 400px viewport: ~1.75rem (minimum) */
  /* At 800px viewport: 4vw = 32px = 2rem */
  /* At 1200px viewport: ~3rem (maximum) */
}

This replaces verbose breakpoint-based font scaling with a single line. The CSS Clamp Calculator generates the exact formula based on your min/max sizes and breakpoints.

Common Mistakes

Using px for font-size — This is an accessibility failure. Users who increase their browser's default font size (a common accessibility accommodation) will see no change on your site. Every font-size: 16px should be font-size: 1rem.

The em nesting trap — Nesting elements that all use em for font-size causes exponential scaling. A font-size: 1.2em inside another font-size: 1.2em gives you 1.44× the root size, not 1.2×. Switch to rem to eliminate this entirely.

Using 100vh on mobile — Without dvh (and a vh fallback), full-screen layouts overflow behind the address bar on iOS and Android. Use height: 100dvh for elements that must truly fill the screen.

Mixing em and rem inconsistently — Pick a convention. The most common is: rem for all font-size declarations, em for padding/margin inside components so they scale with local font size.

Quick Reference

Use the px to rem Converter to translate pixel values from designs into rem equivalents. For a broader range of unit conversions — including em, vw, and percent calculations — the CSS Unit Converter handles the math. For fluid typography, the CSS Clamp Calculator generates the clamp() formula for your exact requirements.

CSS units are not a style choice — they're a structural decision that affects accessibility, responsive behavior, and maintainability. Use rem for text, px for hard edges, and dvh/vw for viewport-relative layouts, and you'll avoid 90% of the gotchas.