px, rem, em, vh — when to use each CSS unit

A practical guide to choosing the right CSS unit for every situation: layout, typography, spacing, and responsive design.

5 min read CSS Accessibility
Choosing the wrong CSS unit is one of the most common mistakes in front-end development. Use px everywhere and your typography breaks when users zoom their browser. Use em carelessly and your padding compounds in unexpected ways. The good news: once you understand why each unit exists, the right choice becomes obvious.
This guide covers px, rem, em, vh, vw — the five units you'll use in 95% of your projects — with practical rules, code examples, and an accessibility-first perspective. At the end, a conversion table and a one-page decision guide you can bookmark.

Absolute vs relative units

CSS units fall into two broad categories. Absolute units have a fixed size that does not change based on anything — they are what they are. Relative units derive their size from some reference: a parent element, the root font size, or the viewport dimensions.

Unit Type Relative to
pxAbsoluteCSS pixel (device-independent)
pt, cmAbsolutePhysical measurement (print use)
remRelativeRoot <html> font-size
emRelativeCurrent element's font-size
%RelativeParent element's dimension
vh, vwRelativeViewport height / width
dvh, dvwRelativeDynamic viewport (accounts for browser UI)

For screen-based design, prefer relative units for typography and spacing. Absolute units are best reserved for elements that should never scale: borders, outlines, and decorative details.

px — pixel precision

A CSS pixel is not a physical screen pixel. It is a device-independent unit defined such that one CSS pixel equals approximately 1/96th of an inch at arm's length. On high-DPI (Retina) screens, one CSS pixel maps to 2 or 3 physical pixels — but from CSS's perspective it is still 1px.

When to use px

  • Borders and outlines: border: 1px solid — these should never scale
  • Box shadows: box-shadow: 0 2px 8px rgba(0,0,0,.15)
  • Icon sizes when paired with a fixed-size icon system
  • Media query breakpoints (though em is safer — see Decision guide)

When NOT to use px

  • font-size — overrides the user's browser default, failing WCAG 1.4.4
  • line-height — prefer unitless (1.5) or rem
  • padding and margin when you want them to scale with font size

Accessibility rule: if a user sets their browser to 200% text size, px-based fonts ignore it. rem-based fonts honour it. This is not optional — it is a WCAG 2.1 Level AA requirement.

Free Tool CSS Unit Converter Convert px, rem, em, vh and more — paste a value and get all equivalents instantly

rem — root-relative scaling

rem stands for root em. It is always relative to the font-size set on the <html> element. The browser default is 16px, so 1rem = 16px unless you change it.

/* Default: 1rem = 16px */
h1 { font-size: 2rem; }    /* 32px */
p  { font-size: 1rem; }    /* 16px */
.small { font-size: .75rem; } /* 12px */

Because rem is anchored to the root, it does not compound when elements are nested — unlike em. This makes it the default choice for font sizes and spacing throughout a project.

The 62.5% trick

Setting html { font-size: 62.5%; } makes 1rem = 10px, which simplifies mental arithmetic (1.6rem = 16px). It is widely considered an anti-pattern today because:

  • It overrides the user's browser font-size preference before your CSS loads
  • Third-party components that rely on the 16px baseline will render incorrectly
  • Modern tooling (CSS custom properties, clamp()) removes the need for base-10 math

Use rem with the default 16px root. Divide by 16 mentally or use a px-to-rem converter.

em — context-relative sizing

em is relative to the current element's font-size. If no font-size is set on the element, it inherits from its parent — which is why em can compound when elements are nested.

/* Compounding example */
.parent { font-size: 1.2em; }  /* 19.2px if parent is 16px */
.child  { font-size: 1.2em; }  /* 23.04px — 1.2 × 19.2px */

When em shines

Em is the right unit when you want spacing or sizing to scale proportionally with the component's own font-size, not the global root:

.btn {
  font-size: 1rem;
  padding: .5em 1.2em;  /* scales with btn font-size */
}
.btn-large {
  font-size: 1.25rem;
  /* padding automatically scales — no overrides needed */
}

This pattern — em for padding inside a component that has its own font-size set in rem — gives you the best of both worlds: global scale control with local proportional scaling.

When to avoid em

  • Global font sizes — use rem to avoid compounding across the DOM tree
  • Layout dimensions — use rem, %, or viewport units instead
Free Tool px to rem Converter Convert any pixel value to rem in one click, with adjustable root font size

vh and vw — viewport units

vh (viewport height) and vw (viewport width) are each equal to 1% of the viewport's corresponding dimension. They are ideal for layouts that need to fill or be proportional to the screen.

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

The 100vh mobile problem

On mobile browsers, the address bar and bottom navigation chrome eat into the visible area — but they are not subtracted from 100vh. This means a 100vh element is taller than the visible screen, causing a scrollbar to appear even when you don't want one.

The modern fix: dvh

The dvh (dynamic viewport height) unit was introduced to solve this. It updates as the browser UI appears and disappears:

.hero {
  height: 100vh;   /* fallback for older browsers */
  height: 100dvh;  /* dynamic — accounts for collapsible browser chrome */
}

dvh has excellent browser support as of 2024. Always include the vh fallback for the rare case where it is not supported.

Other viewport units

  • svh / svw — small viewport (browser UI fully visible)
  • lvh / lvw — large viewport (browser UI hidden)
  • vmin / vmax — smaller/larger of vh and vw

Quick conversion table (base 16px)

When you know the pixel value but need the rem equivalent, divide by 16. This table covers the most common sizes:

px rem em (1:1)
80.5rem0.5em
120.75rem0.75em
140.875rem0.875em
161rem1em
181.125rem1.125em
201.25rem1.25em
241.5rem1.5em
322rem2em
483rem3em
644rem4em

Need to convert an entire stylesheet? Use the CSS Unit Converter tool.

Decision guide

When in doubt, use this table as a quick reference:

Property / Use case Recommended unit
Font sizerem
Padding / margin (global)rem
Padding inside a component (scales with its font-size)em
Borders, outlines, box shadowspx
Layout columns / widths% or fr (CSS Grid)
Hero / full-screen sectionsdvh with vh fallback
Media query breakpointsem (most accessible) or rem
Line-heightUnitless (1.5) or rem
Responsive font size (fluid)clamp() with rem values

Fluid typography with clamp() is a powerful pattern: font-size: clamp(1rem, 2.5vw, 1.5rem) sets a minimum, a fluid middle, and a maximum — all in one line. Use the Font Size Clamp Generator to build these values visually.

Free Tool Font Size Clamp Generator Build fluid responsive typography with clamp() — set min, max and fluid range visually

Frequently asked questions

What is the difference between absolute and relative CSS units?+
Absolute units (px, pt, cm) have a fixed size that does not change based on context. Relative units (rem, em, %, vh) scale based on a reference — the root font size, parent element, or viewport. For responsive and accessible designs, relative units are generally preferred for typography and spacing.
Why should I use rem instead of px for font sizes?+
When users set a larger default font size in their browser (an accessibility need), rem-based sizes scale accordingly. px-based sizes remain fixed and ignore the user's preference. Using rem for font-size respects user settings and is required to pass WCAG 1.4.4 (Resize Text).
When should I use em instead of rem?+
Use em when you want spacing or sizing to scale relative to the component's own font-size, not the global root. A button's padding set in em will grow proportionally if the button's font-size increases, maintaining consistent visual weight.
What is the 62.5% trick and should I use it?+
Setting html { font-size: 62.5% } makes 1rem = 10px, simplifying mental math (1.6rem = 16px). It is considered an anti-pattern because it overrides the user's browser default and can break third-party components that rely on the 16px base.
Why does 100vh behave unexpectedly on mobile?+
On mobile browsers, the address bar and UI chrome consume viewport space but are not subtracted from 100vh. This causes 100vh elements to extend below the visible area. The modern fix is to use 100dvh (dynamic viewport height), which accounts for collapsible browser UI. Add a fallback: height: 100vh; height: 100dvh.
Which CSS unit is best for media query breakpoints?+
The community is divided: px is simpler to read, but em and rem breakpoints fire correctly when the user has changed their root font size. Using em (e.g. @media (max-width: 48em)) is the most robust approach for accessibility.
How do I convert px to rem quickly?+
Divide the px value by 16 (the default root font size): 24px ÷ 16 = 1.5rem. If you use a different root size, divide by that value instead. A conversion tool can automate this for entire stylesheets.