In CSS, a great many properties boil down to numbers. Those numbers might be integers, decimals, or percentages. Whichever form they take, the unit attached to that number ultimately decides how the browser computes the resulting value. A "length" here means any distance expressed numerically, from physical dimensions to measurements of time or geometric angles. The current CSS Values and Units Module Level 4 specification defines a substantial taxonomy of these units. Many are fairly recent additions, and they fall into several broad categories that aren't always immediately obvious.

Types of Units

CSS units can be grouped into distinct types. Some are absolute, meaning they map to a fixed physical size. Others are relative, sizing themselves according to some other value, such as the font size of a parent element or the viewport's dimensions. There are also units for angles, time, and resolution, each serving a particular set of properties.

Absolute Lengths

On screens, most absolute units are tied to a reference pixel. The specification defines the classic set: px for pixels, cm for centimeters, mm for millimeters, in for inches (exactly 96 pixels), pc for picas (1/6 of an inch), and pt for points (1/72 of an inch). While these originate from physical media, they are all defined relative to the CSS pixel for consistent rendering regardless of the device's actual resolution.

Relative Units

Relative units are far more flexible. They are computed from an external reference rather than a fixed size. The most common are the font-relative units:

  • em is relative to the font size of the current element (for font properties) or the parent element (for other properties).
  • rem refers to the root element's (``) font size, simplifying scalable typography from the top down.
  • ch measures the advance width of the "0" (zero) glyph in the current font.
  • ex corresponds to the x-height of the font — the height of a lowercase "x".

Viewport units are another major category. Introduced to handle responsive layouts without JavaScript, they respond to the size of the browser window:

  • vw is 1% of the viewport's width.
  • vh is 1% of the viewport's height.
  • vmin equals the smaller of vw and vh.
  • vmax equals the larger of the two.

The specification's newer additions extend the viewport and font-relative families. vi and vb are 1% of the viewport's inline and block axis sizes, respectively. On the font side, cap reports the cap height (the height of capital letters), ic uses the width of the "水" (CJK ideographic) glyph, and lh and rlh follow the built-in line-height for the current element or the root element, respectively.

Furthermore, container query units have arrived. These are relative to the size of a query container rather than the whole viewport, enabling components to scale within their own layout context. The units cqw, cqh, cqi, cqb, and cqmin/cqmax work in a manner parallel to viewport units but target the container.

Percentages, Angles, Time, and Beyond

Percentages are unique: they are not truly lengths but resolve to lengths depending on the property they are assigned to. The spec treats them as a separate unit category, often needing to be defined contextually—for font sizes, they reference the parent font size, while for widths, they reference the containing block's width.

When elements are rotated, we need angle units. The spec includes deg (degrees, 1/360 of a full rotation), rad (radians, matching mathematical conventions), grad (gradians, with 400 per full rotation), and turn (whole revolutions). For animations and transitions, time is measured in seconds (s) and milliseconds (ms). Finally, there are resolution units for media queries and images: dpi (dots per inch), dpcm (dots per centimeter) and dppx (dots per pixel). Note that the exact rendering of some newer units is still being refined as the level 4 specification matures.

Quick Reference

The tables below cover the full range of CSS units across eight categories:
UnitName
cmCentimeters
mmMillimeters
QQuarter-millimeters
inInches
pcPicas
ptPoints
pxPixels
UnitRelative to…
emThe font size of the element, or its nearest parent container
exThe 0-height of the element’s font 
capThe cap height (the nominal height of capital letters) of the element’s font 
chThe width of the 0 character of the font in use
icThe average width of a full glyph of the font in use, as represented by the “水” (U+6C34) glyph
remThe font-size value that’s set on the root (html) element
lhThe line-height value that’s set on the element 
rlhThe line-height that’s set on the root (html) element 
vw1% of viewport’s width
vh1% of viewport’s height
vi1% of viewport’s size in the root element’s inline axis
vb1% of viewport’s size in the root element’s block axis
vminEqual to 1% of the vw or vh, whichever is smaller
vmaxEqual to 1% of the vw or vh, whichever is larger
vw1% of viewport’s width
vh1% of viewport’s height
vi1% of viewport’s size in the root element’s inline axis
vb1% of viewport’s size in the root element’s block axis
vmin1% of the vw or vh, whichever is smaller
vmax1% of the vw or vh, whichever is larger
UnitRelative to
cqw1% of a query container’s width
cqh1% of a query container’s height
cqi1% of a query container’s inline size
cqb1% of a query container’s block size
cqminThe smaller value of cqi or cqb
cqmaxThe larger value of cqi or cqb
UnitDescription
degThere are 360 degrees in a full circle.
gradThere are 400 gradians in a full circle.
radThere are 2π radians in a full circle.
turnThere is 1 turn in a full circle.
UnitDescription
sThere are 60 seconds in a minute, but there is no unit for minutes.
msThere are 1,000 milliseconds in a second.
UnitDescription
frOne fraction of the free space in a grid container.
UnitDescription
dpiDots per inch
dpcmDots per centimeter
dppxxDots per pixel unit
UnitDescription
HzRepresents the number of occurrences per second
kHzOne kiloHertz is equal to 1000 Hertz.

Number Types and Units

All numeric values in CSS fall into one of two buckets: absolute or relative. Absolute units have a fixed, unchanging size. Relative units compute their final value based on something else—a parent element, a font, the viewport, or a container. Before digging into individual units, note that CSS distinguishes among several number types:
  • Integers: unit-less whole numbers, e.g. 3
  • Numbers: integers with decimals, e.g. 3.2
  • Dimensions: a number with a unit, e.g. 3.2rem
  • Ratios: quotients of two divided numbers, e.g. 3/2
  • Percentages: relative values, e.g. 3%

Absolute Length Units

An absolute unit always resolves to the same physical size, no matter what else is happening on the page. Pixel (px) is the most common example. It corresponds to the smallest building block of a display, so its physical size varies with screen resolution—but within a given context it is constant. Absolute units can be grouped by what they measure: Length units describe physical dimensions—values like cm, in, pc, and pt—the sorts of measurements found on a tape measure or in print design. Their values are literal:
UnitName
cmCentimeters
mmMillimeters
QQuarter-millimeters
inInches
pcPicas
ptPoints
pxPixels
Angle units are geometric values used for shape dimensions, gradient directions and rotation transforms:
UnitNameDescriptionExample
degDegreesA full circle is equal to 360deg.rotate(180deg)
gradGradiensA full circle is equal to 400grad.rotate(200grad)
radRadiensA full circle is equal to (i.e., 2 × 3.14), or about 6.2832rad.rotate(3.14rad)
turnTurnsA full circle is 1turn, like a bicycle wheel making one full rotation.rotate(.5turn)
Time units measure durations in seconds (s) and milliseconds (ms) only:
UnitNameDescriptionExample
sSecondsOne full minute of time is equal to 60s.animation-duration: 2s
msMillisecondsOne full second of time os equal to 1000ms.animation-duration: 2000ms
Frequency units are specced for sound pitch, but are not supported by any browser at this writing:
UnitNameDescriptionExample
HzHertzMeasures the number of frequencies per second<source src="tubthumping.mp3" type="audio/mpeg" frequency="100Hz">
kHzKilohertzA value of 1Hz is equal to 0.001kHz.<source src="tubthumping.mp3" type="audio/mpeg" frequency="0.1kHz">
Resolution units describe pixel density, commonly used in media queries to target specific displays:
img {
  max-width: 500px;
}

/* Double the resolution and above */
@media (min-resolution >= 2dppx) {
  img {
    max-width: 100%;
  }
}
UnitNameDescriptionExample
dpiDots per inchThe number of dots packed into one inch of space.@media
(min-resolution: 96dpi) {}
dpcmDots per centimeterThe number of dots packed into one centimeter of space.@media
(min-resolution: 960dpcm) {}
dppx (or x)Dots per pixelThe number of dots packed into one pixel of space.@media
(min-resolution: 1dppx) {}
Note that the specification also defines an infinite value for resolution—useful when targeting vector output or comparing values in range contexts, where it is treated as larger than any possible resolution.

Relative Units

Relative units depend on some other value. For instance, an element set to 200px tall will never change height, but the same element at width: 50% dynamically takes up half the available space of its parent—shrinking and growing as that parent resizes:
<div class="box">
  I am 200 pixels tall
</div>
.box {
  height: 200px;
}
<div class="box">
  I am 200 pixels tall and 50% wide
</div>
.box {
  height: 200px;
  width: 50%;
}
This is the key insight for relative units: the browser resolves the declared value into a computed pixel length at render time.

Percentages

A percentage compares the element to its containing block. With a parent at width: 1000px, a child with width: 25% computes to 250px:
UnitNameRelative to…
%PercentThe size of the element’s parent container.

Font-Relative Units

Both em and rem anchor sizing to font size. Changing the font-size of the parent (for em) or the root <html> element (for rem) updates all relative values automatically:
UnitNameRelative to…
emElementThe font-size value of the element’s parent container.
remRoot elementThe font-size value of the <html> element.
chCharacterThe width of the 0 character relative to the parent element’s font. The computed width may update when replacing one font with another, except for monospace fonts that are consistently sized.
rchRoot characterThe same thing as a ch unit except it is relative to the font of the root element, i.e. <html>.
lhLine heightThe line-height value of the element’s parent container.
rlhRoot element line heightThe line-height value of the <html> element.
capCapital letterThe height of a capital letter for a particular font relative to the parent element.
rcapRoot capital letterThe same measure as cap but relative to the root element, i.e. <html>.
icInternational characterThe width of a CJK character, or foreign glyph, e.g. from a Chinese font, relative to an element’s parent container.
ricRoot international characterThe same measure as ic but relative to the root element, i.e. <html>.
exX-heightThe height of the letter x of a particular font, or an equivalent for fonts that do not contain an x character, relative to the parent element.
rexRoot x-heightThe same measure as ex but relative to the root element, i.e. <html>.
Additional font-relative units include character-based values like ex, ch, and lh, all of which measure against typographic features:
Four lines drawn over a line of text illustrating the ascender height, x-height, baseline, and descender height.
For example, a value like width: 10ch computes to a different pixel length depending on the font in use, since ch equals the width of one character.

Viewport-Relative Units

Viewport units differ from percentages: they are relative to the browser window, not any parent. An element with width: 100vw and height: 100vh fills the entire viewport:
UnitNameRelative to…
vh / vwViewport Height / Viewport WidthThe height and width of the viewport (i.e., visible part of the screen), respectively.
vmin / vmaxViewport Minimum / Viewport MaximumThe lesser and greater of vh and vw, respectively.
lvh / lvwLarge Viewport Height / Large Viewport WidthThe height and width of the viewport when the device’s virtual keyboard or browser UI is out of view, leaving a larger amount of available space.
lvb / lviLarge Viewport Block / Large Viewport InlineThese are the logical equivalents of lvh and lvw, indicating the block and inline directions.
svh / svwSmall Viewport Height / Small Viewport WidthThe height and width of the viewport when the device’s virtual keyboard or browser UI is in view, making the amount of available space smaller.
svb / sviSmall Viewport Block / Small Viewport InlineThese are the logical equivalents of svh and svw, indicating the block and inline directions.
dvh / dvwDynamic Viewport Height / Dynamic Viewport WidthThe height and width of the viewport accounting for the available space changing if, say, the device’s virtual keyboard or browser UI is in view.
dvb / dviDynamic Viewport Block / Dynamic Viewport InlineThese are the logical equivalents of dvh and dvw, indicating the block and inline directions.
dvmin / dvmaxDynamic Viewport Minimum / Dynamic Viewport MaximumThe lesser and greater of dvh/dvb and dvw/dvi, respectively.
Illustration of a browser window with intersecting arrows pointing towards the vertical and horizontal extremes of the dimensions.
One important caveat: on mobile devices, the on-screen keyboard changes the viewport size. When the keyboard opens, 100vh becomes the leftover space, not the full screen height. Newer units address this directly:
  • svh: the “small” viewport height, matching the keyboard-open state.
  • lvh: the “large” viewport height, when the keyboard is out of view.
  • dvh: a dynamic value that updates as the keyboard appears or hides.
  • dvmin / dvmax: the lesser or greater of the dynamic viewport dimensions.

Container-Relative Units

Container query units size elements relative to a registered container rather than the viewport. Register any parent with container-type:
.parent-container {
  container-type: inline-size;
}
After that, descendants can be sized in container units. In the rest of the snippet, the child element responds once the container reaches 30ch, shrinking to half the container’s inline size (50cqi):
.child-element {
  background: rebeccapurple;
  width: 100%;

  @container parent (width > 30ch) {
    .child-element {
      background: dodgeblue;
      width: 50cqi;
    }
  }
}

Unit-less Numbers

Some CSS properties intentionally omit units. Unit-less zero is always allowed—zero computes to zero regardless of context—but other cases use raw numbers for properties like z-index, line-height, or opacity:
aspect-ratio: 2 / 1; /* Ratio */
column-count: 3; /* Specifies a number of columns */
flex-grow: 1; /* Allows the element to stretch in a flex layout */
grid-column-start: 4; /* Places the element on a specific grid line */
order: 2; /* Sets the order of elemnents in a flex or grid layout */
scale: 2; /* The elementis scaled up or down by a factor */
z-index: 100; /* Element is placed in a numbered layer for stacking */
zoom: 0.2;  /* The element zooms in or out by a factor */
border: 0; /* No border */
box-shadow: 0 0 5px #333; /* No shadow offset */
margin: 0; /* No margin */
padding: 0; /* No padding */

Custom Units with @property

Without intervention, CSS treats unrecognized custom property values as strings, not numbers. For example, attempting to animate a hue from 0 to 360 fails because the variable is read as text:
/* 👎 */
.element {
  --hue: 0;
  
  animation: rainbow 10s linear infinite;
  background: linear-gradient(hsl(--hue 50% 50%);
}

@keyframes rainbow {
  from { --hue: 0; }
  to { --hue: 360deg; }
}
Registering the variable with @property defines its syntax, allowing CSS to interpret and animate the numeric value correctly:
@property --hue {
  syntax: "<number>";
  initial-value: 0;
  inherits: true;
}
/* 👍 */
@property --hue {
  syntax: "<number>";
  initial-value: 0;
  inherits: true;
}

.element {
  --hue: 0;
  
  animation: rainbow 10s linear infinite;
  background: linear-gradient(hsl(--hue 50% 50%);
}

@keyframes rainbow {
  from { --huw: 0; }
  to { --hue: 360deg; }
}

Practical Unit Choices

Some pairing is unavoidable: gradients require angle units, and color functions like hsl() expect percentage-based saturation and lightness:
.element {
  background: linear-gradient(
    135deg, red, blue;
  )
}
.element {
  background: hsl(0 100% 10%);
}
Alpha channels use an integer or number:
.element {
  background: hsl(0 100% 10% / 0.5); /* or simply .5 */
}
Elsewhere, the answer is usually situational, but a few rules of thumb apply.

Use rem and em for font sizes

Root-relative rem values flow from the <html> font size, so adjusting that single knob scales all text proportionally:
html {
  font-size: 18px; /* Inherited by all other elements */
}

.parent {
  font-size: 1rem; /* Updates when the `html` size changes */
}

.child {
  font-size: 1em; /* Updates when the parent size changes */
}

Write 0 without a unit

Dropping units from zero saves a few bytes with no behavioral difference, since 0 always evaluates to zero.

Prefer container units for component-level responsive sizing

Container units beat viewport units whenever the target element sits inside a registered container:
.parent {
  container: my-container / inline-size; /* Looks at width */
}

.child {
  display: flex;
  flex-direction: column;
  max-width: 100vh; /* 100% of the viewport */
}

/* When the container is greater than 600px wide */
@container my-container (width >= 600px) {
  .child {
    flex-direction: row;
    max-width: 50%; /* 50% of the parent elenent */
  }
}
Because the child’s size depends on the container, not the whole screen:
.parent {
  container: my-container / inline-size; /* Looks at width */
}

.child {
  display: flex;
  flex-direction: column;
  max-width: 100cqi; /* 100% of the container */
}

/* When the container is greater than 600px wide */
@container my-container (width >= 600px) {
  .child {
    flex-direction: row;
    max-width: 50cqi; /* 50% of the container */
  }
}

Use percentages when you don't have a container

Percentage values are relative to whatever parent the element is in, regardless of whether that parent is registered as a container. They are a safe fallback for components that get dropped into arbitrary contexts.

Use viewport units for full-page layouts

Container units handle component sizing; but for arranging full-page sections, viewport units are still the right tool for establishing higher-level layout scale.

Worked Examples

em and rem in action

An em unit multiplies by the font size of the current element’s parent. With a parent at font-size: 20px, child text set to 1.5em computes to 30px:
20px * 1.5 = 30px
A rem value behaves identically but anchors to the root element’s font size, which defaults to 16px:
/* This is the browser's default font size */
html {
  font-size: 16px;
}

.box {
  font-size: 1.5rem; /* 16px * 1.5 = 24px */
}
Changing that root font size instantly updates every rem measurement:
html {
  font-size: 18px;
}

.box {
  font-size: 1.5rem; /* 18px * 1.5 = 27px */
}

The ch character unit

One ch equals the width of the zero character in the current font. Setting width: 10ch on a paragraph breaks the text after the tenth character, keeping complete words intact:
<p>The big brown dog lazily jumped over the fence.</p>
p {
  width: 10ch;
}
This makes ch well suited for controlling readable line lengths.

The lh line-height unit

The lh unit equals the line-height of the element’s parent:
.parent {
  line-height: 1.5;
}

.child {
  height: 3lh; /* 3 * 1.5 = 4.5 */
}
It is useful for sizing elements exactly to a certain number of text lines, keeping consistent dimensions that scale with the font.