Overview

CSS has more than a dozen length units. Picking the wrong one produces layouts that break on zoom, small screens, or devices with dynamic browser chrome. This card maps each unit to the situation where it wins and the situations where it fails. For cascade and custom-property patterns, see css-custom-properties.

Absolute units

Use only when the output maps to physical rendering (print, canvas, device pixel counts).

UnitEquivalentBest use
px1 CSS pixel (device-independent)Borders, box shadows, media query breakpoints, hairline rules.
pt1/72 inchPrint stylesheets only.
cm / mmPhysical centimetres/millimetresPrint layouts; meaningless on screen.
in1 inch = 96pxPrint; never screen.

px is the only absolute unit with a regular role in screen CSS. All others belong in @media print blocks.

Font-relative units

Scale with the element or root font size.

UnitRelative toWhen it wins
emFont size of the current element.Component-local spacing that should scale with the component’s own font size; icon sizes.
remFont size of the root <html> element.Site-wide typographic scale, spacing tokens. Unaffected by nested font-size overrides.
chWidth of the 0 glyph in the current font.Prose column width (max-width: 65ch is a reliable readable-line constraint).
exHeight of the x glyph.Rarely useful; vertical alignment of text glyphs.
lhLine height of the current element.Gap that matches the rhythm of surrounding text.
capHeight of capital letters.Cap-height-relative icon alignment.

Prefer rem for most spacing and sizing. Reserve em for values that must scale with the local font (padding inside buttons, icon sizes next to text).

Percentage

UsageComputed against
Width / margin / padding (horizontal)Content width of the containing block.
HeightHeight of the containing block (only works when the parent has a defined height).
font-sizeFont size of the parent element.
line-heightfont-size of the element itself.
transform: translate(50%)Dimensions of the element itself, not the parent.

% on height silently does nothing if no ancestor has a fixed height. Use min-height: 100dvh instead.

Viewport units

UnitWhat it measuresNotes
vw1% of viewport width.Fluid typography, hero sections. Includes scrollbar width in some browsers.
vh1% of viewport height.Avoid for mobile full-screen layouts; see dynamic units below.
vmin1% of the smaller viewport dimension.Square elements that fit on any orientation.
vmax1% of the larger viewport dimension.Backgrounds that must always cover.
svhSmall viewport height (browser chrome fully visible).Safe lower bound for mobile; use for fixed footers.
lvhLarge viewport height (browser chrome hidden).Use for elements that can expand when chrome disappears.
dvhDynamic viewport height (updates as chrome shows/hides).Full-screen app shells; causes reflow on scroll.
svw / lvw / dvwWidth equivalents.Mirror the height variants.

Prefer dvh for min-height: 100dvh on full-page containers. The reflow cost is acceptable; the wrong fixed height is not.

Grid and flex units

UnitContextWhat it does
frgrid-template-* only.One fraction of the free space after fixed tracks are resolved. 1fr 2fr gives a 1:2 split.
%Flex children.Percentage of the flex container’s main-axis size, but flex-basis overrides it.
autoGrid or flex items.Shrinks to content in flex; fills remaining space in grid when combined with minmax.
min-contentGrid tracks or flex basis.Narrowest size the content allows without overflow.
max-contentGrid tracks or flex basis.Widest intrinsic size, ignoring the container.
fit-content(N)Grid tracks.min(max-content, max(min-content, N)); clamps a track.

fr units only work inside grid-template-columns and grid-template-rows. They have no meaning elsewhere.

Container-relative units (cq*)

Require container-type: inline-size (or size) on an ancestor.

UnitRelative to
cqi1% of the container’s inline size.
cqb1% of the container’s block size.
cqw / cqhExplicit container width / height.
cqmin / cqmaxSmaller / larger container dimension.

Use container units inside component CSS so the component adapts to its slot, not the viewport. See css-container-queries for the full pattern.

Common gotchas

  • em in padding and margin is relative to the element’s own font-size, not the parent’s. This surprises when the element has an inherited font size.
  • vh on mobile does not account for the URL bar. The element is taller than the visual viewport when the chrome is visible. Use dvh or svh instead.
  • % heights require every ancestor to have an explicit height. Setting height: 100% on a child of an auto-height parent has no effect.
  • fr units in grid-template-columns do not account for gap. A 1fr track is narrower than expected when gap is set.
  • ch width varies by font. 65ch in one typeface may not equal 65ch in another. Define a fallback max-width in px when exact prose width matters.
  • rem ignores browser-level font size overrides if the root html element sets font-size in px. Set the root in % (e.g., font-size: 100%) to respect the user’s preference.