CSS 3 min read

CSS Units Explained: px, em, rem, %, vw and clamp()

Choosing the right CSS unit makes layouts responsive and text accessible. Here's when to use px, em, rem, percentages, viewport units and clamp() — with practical rules of thumb.

On this page

Key takeaways

  • Use rem for font sizes so text respects user settings; px for borders and fine details.
  • %, fr and viewport units (vw, dvh) handle fluid layouts.
  • clamp() creates fluid sizes with sensible minimums and maximums — often replacing several media queries.

CSS has more than a dozen length units, and choosing the wrong one causes real problems: text that ignores a visitor’s font-size preference, full-screen sections that jump on mobile, or padding that’s huge on desktop and cramped on phones. Here’s what each unit is for.

Absolute vs relative units#

Unit Relative to Best for
px CSS pixel (not device pixel) Borders, shadows, small fixed details
rem Root (html) font size, usually 16 px Font sizes, spacing scales
em Current element’s font size Padding that scales with its text (buttons), icon sizes
% Parent’s size (varies by property) Widths inside containers
vw / vh 1% of viewport width / height Fluid type, full-width sections
dvh / svh / lvh Dynamic / small / large viewport height Full-height mobile sections
ch Width of the “0” character Readable line lengths: max-width: 70ch
fr Fraction of free space (Grid only) Grid columns
cqi 1% of the container’s inline size Container-query components

Why rem for font sizes?#

Some people increase their browser’s default font size because they need larger text. If you set font-size: 14px, you override that choice. With font-size: 0.875rem, text scales with their preference. That’s an accessibility win at no cost.

em: useful but compounding#

em is relative to the element’s own font size, which itself may be relative to its parent. Nested em sizes compound (0.8em inside 0.8em = 0.64 of the original). Use em deliberately — for example, button padding of 0.75em 1.25em stays proportional whether the button text is small or large.

Need a hand with this?

Get a quick, honest review of your website’s SEO.

Chat on WhatsApp

The 100vh problem on mobile#

On phones, browser toolbars appear and disappear while scrolling. 100vh uses the largest height, so full-screen sections get cut off behind the toolbar. Use the newer units:

.hero { min-height: 100svh; }   /* fits with toolbars visible */
.app  { height: 100dvh; }       /* adjusts as toolbars change */

clamp(): fluid sizes with limits#

h1       { font-size: clamp(2rem, 1.2rem + 3vw, 3.5rem); }
.section { padding-block: clamp(40px, 7vw, 96px); }
.wrap    { width: min(100% - 32px, 1200px); margin-inline: auto; }
  • clamp(min, preferred, max) — never smaller than min, never larger than max, fluid in between.
  • Mixing rem with vw in the preferred value keeps text zoomable (pure vw text doesn’t scale with browser zoom — an accessibility issue).
  • min() and max() handle simpler cases.

A practical default system#

  • Body text: 1rem–1.125rem, line-height 1.6–1.8 (unitless).
  • Headings: clamp() with rem + vw.
  • Spacing: a small scale in rem or px (4, 8, 12, 16, 24, 32, 48…).
  • Layout widths: %, fr, min() and ch for text.
  • Borders and hairlines: px.

CSS units FAQ#

Is px bad?#

No. CSS pixels scale with device density and zoom. Just avoid px for font sizes if you want to respect user font settings.

Should line-height have units?#

Use a unitless number like 1.6; it scales correctly for nested elements with different font sizes.

What is a CSS pixel on retina screens?#

A CSS pixel can map to 2, 3 or more device pixels. That’s why images need higher-resolution versions via srcset.

Found this useful? Share it

Join the discussion

Your email address will not be published. Required fields are marked *

Security code image. If you cannot read it, press refresh or contact me on WhatsApp.