Skip to content

CSS Units Converter

Convert between CSS units: px, rem, em, %, pt, vh, vw.

CSS lets you express lengths in many different units. They’re not interchangeable — each one is relative to something different, and that something determines how the value behaves at different screen sizes, zoom levels, and contexts. The tool above converts between units in your browser; nothing leaves your machine.

The unit families

FamilyUnitsRelative to
Absolutepx, pt, pc, cm, mm, inFixed (in CSS pixels, not physical pixels)
Font-relativeem, rem, ex, chA font size somewhere in the cascade
Viewport-relativevh, vw, vmin, vmax, vi, vbThe viewport dimensions
Container-relativecqw, cqh, cqi, cqb (newer)The size of a containing element
Percentage%The corresponding property of the parent

Two units that produce the same number of CSS pixels in one context can produce different numbers in another. That’s the point.

px — the unit that isn’t really pixels

1px in CSS is not 1 device pixel. It’s 1/96 of an inch in CSS’s reference coordinate system. On a high-DPI display, the browser maps each CSS pixel to multiple device pixels (e.g., 2× on a Retina display means 1 CSS px = 4 device px). On any display, when the user zooms, CSS px scales with the zoom.

px is the most-commonly-used unit and the easiest to reason about: font-size: 16px means the text is 16 reference units tall, and 16 reference units is the same on every device.

The other absolute units (pt, pc, cm, mm, in) are defined relative to px: 1pt = 1.333px, 1in = 96px. They’re useful in print stylesheets; rare elsewhere.

em — relative to the current element’s font-size

1em equals the computed font-size of the current element.

.parent { font-size: 20px; }
.parent .child { padding: 1em; }
/* .child padding = 20px (its font-size is inherited from .parent) */

.parent .child { font-size: 14px; padding: 1em; }
/* .child padding = 14px (its own font-size, not inherited) */

The trap: em compounds. A nested element whose parent uses em for font-size ends up with multiplied sizes. font-size: 1.2em three levels deep is 1.2 × 1.2 × 1.2 = 1.728× the root size, not 1.2×.

em is appropriate for properties that should scale with the element’s text — the padding around a button should grow when the button’s text grows, for example.

rem — relative to the root font-size

1rem equals the font-size of the <html> element. By default that’s 16px.

:root { font-size: 18px; }
.anywhere { padding: 1rem; }
/* padding = 18px, regardless of nesting */

rem is the modern default for most layout work because it doesn’t compound. Setting :root { font-size: 16px; } and using rem everywhere means the user can change one number to scale the whole site.

% — relative to the parent’s same property

.parent { width: 400px; }
.parent .child { width: 50%; }
/* width = 200px (50% of parent width) */

Different properties can use percentages with different parent references:

  • width: 50% — 50% of parent’s width.
  • padding: 10% — 10% of parent’s width (always width, even for top/bottom padding).
  • font-size: 80% — 80% of parent’s font-size (similar to em).
  • line-height: 150% — 150% of element’s font-size.

Percentage is intuitive for layout but surprising for properties whose parent reference isn’t obvious. Read the spec for each.

vh, vw — relative to the viewport

  • 1vh = 1% of the viewport height.
  • 1vw = 1% of the viewport width.
  • 1vmin = the smaller of vh or vw.
  • 1vmax = the larger.

Useful for elements that should always fit a portion of the screen — full-bleed sections, hero images, modal overlays. The trap on mobile: viewport height is contentious. The browser’s URL bar and bottom nav appear and disappear as the user scrolls; “100vh” can be the viewport size with the nav visible (in some browsers) or without (in others). The newer units svh, lvh, dvh (small/large/dynamic viewport height) clarify which:

UnitDefinition
100vhInconsistent across browsers; legacy
100svhSmallest possible viewport (URL bar + nav both visible)
100lvhLargest possible viewport (URL bar + nav both hidden)
100dvhDynamic — current viewport, changes on scroll

For “fill the screen exactly” today, 100dvh is usually what authors want.

ch — relative to the “0” character’s width

1ch equals the width of the digit 0 in the current font. Useful for setting input widths that fit a fixed number of characters:

input.zip-code { width: 6ch; }

In a monospace font, 1ch is the same for every character. In a proportional font, characters narrower than 0 (l, i, 1) take less space; wider ones (m, w) take more. The unit is approximate for proportional fonts.

When to use which

Use caseRecommended unit
Body font sizerem (so user-zoom of the root scales everything)
Button paddingem (scales with the button’s text)
Container width% or rem
Viewport-fitting herodvh/dvw
Border widthpx (1px borders should always be 1px)
Media query breakpointsem or rem (scales with user-zoom; px doesn’t)
Print stylesheetpt or mm
Input width by character countch
Icon size that scales with textem

The trend over the last decade: less px, more rem and viewport units, more responsive-by-default sizing.

Common pitfalls

  • Using px for media queries. Browsers historically had inconsistent behavior with px-based media queries when the user zoomed. em-based media queries scale with user font preferences and are now the standard.
  • Compounding em accidentally. A 1.2em font-size on a deeply-nested element multiplies by every ancestor’s em. Use rem unless the compounding is intentional.
  • 100vh not fitting on mobile. Discussed above; use 100dvh.
  • Mixing pt and px. They’re not equivalent; 1pt = 1.333px. Pick one for a project.
  • Forgetting that % references different parent properties for different properties. Padding-top’s percentage uses parent width, not parent height. This trips up authors writing aspect-ratio padding.

For other CSS-related tools, see CSS formatter, CSS minifier.