Cheatsheet

CSS Units Cheatsheet

This cheatsheet is a lookup for CSS length units: what each one is measured against, the exact conversion factors, and which one to reach for. It is for developers who keep second-guessing whether to write px, em, rem or vw. The one confusion it clears up is that em means two different things: the parent's font size when used on font-size, and the element's own font size everywhere else.

Quick reference

Absolute units

Absolute units are fixed ratios of each other. On screens, 1 CSS inch is defined as 96px, whatever the physical display.

Unit Name Equals
`px` pixel 1/96 of an inch
`in` inch 96px = 2.54cm
`cm` centimeter 96px / 2.54 = 37.795px
`mm` millimeter 1/10 of a centimeter
`pt` point 1/72 of an inch = 1.333px
`pc` pica 1/6 of an inch = 16px

Font-relative units

Unit Relative to
`em` Font size of the element itself; for the `font-size` property, the parent's font size
`rem` Font size of the root (`html`) element
`ex` x-height of the element's first available font
`ch` Advance width of the `0` glyph in the element's font
`cap` Cap height of the font (height of capital letters)
`ic` Advance of the CJK water ideograph (U+6C34)
`lh` Computed `line-height` of the element
`rlh` Computed `line-height` of the root element
`rch`, `rex`, `rcap`, `ric` The `ch`, `ex`, `cap` and `ic` values of the root element

If the browser cannot measure the 0 glyph, the spec says ch falls back to 0.5em wide.

Viewport units

All of these are 1% of a viewport dimension. The prefix picks which viewport size is used.

Unit Measures
`vw`, `vh` 1% of viewport width, height
`vi`, `vb` 1% of the viewport size on the inline, block axis
`vmin`, `vmax` 1% of the smaller, larger of width and height
`lv*` (`lvh`, `lvw`) Large viewport: browser toolbars retracted. Same as plain `v*`
`sv*` (`svh`, `svw`) Small viewport: browser toolbars expanded
`dv*` (`dvh`, `dvw`) Dynamic viewport: tracks the toolbars as they show and hide

Container query units

These resolve against the nearest ancestor with container-type set, not the viewport.

Unit Measures
`cqw`, `cqh` 1% of the container's width, height
`cqi`, `cqb` 1% of the container's inline, block size
`cqmin`, `cqmax` Smaller, larger of `cqi` and `cqb`

Other and unitless values

Value Meaning
`%` Percentage of a reference that depends on the property: width of the containing block for `width`, parent font size for `font-size`
`fr` Fraction of free space in a grid track; only valid in grid track lists
`deg`, `rad`, `turn` Angles; 360deg = 1turn
`s`, `ms` Time; 1s = 1000ms
`dppx`, `x` Resolution; 1dppx = 1 device pixel per CSS pixel
`0` The only length that may drop its unit

Common patterns

Compare em and rem inside nested elements

html { font-size: 20px; }
.a { font-size: 1.5em; }    /* depth 3 inside .a: 20 x 1.5 x 1.5 x 1.5 */
.b { font-size: 1.5rem; }   /* depth 3 inside .b: 20 x 1.5 */

A third nested element computes to 67.5px with em (the multiplier compounds at each level, starting from the 20px root) and 30px with rem. Use rem for type and spacing so nesting never compounds.

Fluid font size that stops at both ends

html { font-size: 20px; }
h1 { font-size: clamp(1rem, 0.5rem + 2vw, 2rem); }

Computed values from that rule in Chromium 153: 20px at a 375px viewport, 26px at 800px, 35.6px at 1280px and 40px at 2000px. The minimum is 1rem = 20px and the maximum is 2rem = 40px. Mixing rem with vw keeps the text responsive to the user's font-size setting.

Size a text column in characters

p { max-width: 65ch; }

ch tracks the font, so the line length stays near 65 characters when you change fonts. With a 20px monospace font, 10ch computed to 120.406px in Chromium; the exact width depends on the font that renders.

Fill the screen on mobile browsers

.hero { min-height: 100vh; min-height: 100dvh; }

On desktop all of 100vh, 100svh, 100lvh and 100dvh came out identical (600px in a 600px-tall viewport). They differ only on browsers with retractable toolbars. The second declaration overrides the first where dvh is supported.

Size a component from its container

.card-wrap { container-type: inline-size; }
.card-title { font-size: clamp(1rem, 4cqw, 1.5rem); }

In a 600px-wide container, width: 50cqw computed to 300px. Use this for components that move between narrow and wide slots.

Convert between units by hand

px  = rem x root font size        24px / 16 = 1.5rem
pt  = px x 0.75                   16px = 12pt
in  = px / 96                     192px = 2in

The rem result assumes the default 16px root size. Browsers let users change it, so a hard-coded conversion is a snapshot, not a constant.

Pitfalls

  • em compounds in nested elements: a list inside a list at 1.3em grows 1.3x per level. Use rem for font sizes, and keep em for padding or margins that should scale with the element's own text.
  • Setting html font-size in px: html { font-size: 20px } ignores the user's browser font-size preference. Use 100% or leave it unset, and size from rem.
  • Treating 1pt as 1px: 1pt is 1/72 inch, which is 1.33px (Chromium reported 1.32812px). Print stylesheets use pt; screen layouts rarely should.
  • Using vh for full-height mobile sections: on phones 100vh is the large viewport, so the bottom of the section hides behind the address bar. Use svh for content that must stay visible and dvh for exact fit, remembering dvh resizes while scrolling.
  • Expecting vw to exclude scrollbars: the spec sizes viewport units as if scrollbars do not exist, unless the root has overflow: scroll. A 100vw element can cause horizontal scrolling on systems with classic scrollbars.
  • Using a percentage where only a length is allowed: properties such as border-width accept lengths, not percentages. Check the property's value syntax before assuming % works.
  • Unit-less lengths: margin: 10 is invalid and the declaration is dropped. Only 0 may omit its unit.
  • Using cq units with no container: with no ancestor that has container-type, the units fall back to the small viewport size, so the layout looks right until the component is moved.

Related ZipKit tools

Related cheatsheets