CSSch, ex, cap & other type units

ch, ex, cap & other type units

CSS has a set of units that are relative to the font's own metrics — the actual dimensions of glyphs in the current typeface. These units are invaluable for typography-aware sizing: making a container exactly wide enough for a comfortable line length, sizing elements relative to the x-height of the font, or scaling decorations to match uppercase letters. They're niche compared to rem and em, but knowing them gives you precision that's hard to achieve otherwise.

The type-relative units

Unit

Based on

Browser support

ch

The advance width of the 0 (zero) character in the current font

Excellent — all modern browsers

ex

The x-height of the font — height of a lowercase x

Excellent

cap

The cap height — height of an uppercase letter

Good — Chrome/Edge/Firefox, partial Safari

ic

The advance width of the CJK water ideograph

Growing — intended for CJK text

lh

The computed line-height of the element

Growing — Chrome 109+, Firefox 120+

rlh

The computed line-height of the root element

Growing

ch — character width unit

1ch is the width of the 0 (zero) glyph in the current font. Because 0 is a representative average-width character in most fonts, ch is a great proxy for "one character width". This makes it extremely useful for setting optimal line lengths and sizing form inputs:

CSS
/* Optimal reading line length: 60–80 characters */
.prose {
  max-width: 65ch;
  /* This adapts to the font — a wider font gets a physically wider max-width */
}

/* A password input that fits exactly 8 characters */
input[type="password"] {
  width: 8ch; /* plus a bit for borders — approximate, not pixel-perfect */
}

/* A fixed-width code editor column guide */
.code-editor {
  max-width: 80ch;
  font-family: 'Fira Code', monospace;
  /* In a monospace font, 80ch is exactly 80 characters wide */
}

/* Note: in proportional fonts, ch is based on '0' width,
   not the average width of all characters — vary by font */
In monospace fonts, ch is exactly one character wide — in proportional fonts, it's approximately average width (the '0' is representative but not exact)
`ch` is most precise in monospace fonts like `Courier New` or `Fira Code`, where every character is the same width. In proportional fonts like Georgia or system-ui, the `0` glyph is close to average but not exact. For line length limits, an approximation is fine — the difference between `max-width: 65ch` and `max-width: 70ch` doesn't matter practically. For input sizing, add a small buffer.
ex — x-height unit

1ex equals the x-height — the height of the lowercase letter x in the current font. Different fonts have dramatically different x-heights (the ratio of x-height to cap height is called the x-height ratio), so ex adapts to the specific typeface:

CSS
/* Align an icon to the visual centre of text using ex */
.icon {
  height: 1ex;
  width: 1ex;
  vertical-align: middle; /* combined with ex-based height, optically centres */
}

/* A slightly raised small detail — relative to text height */
.badge {
  font-size: 0.75em;
  vertical-align: 0.5ex; /* raises by half an x-height */
}

/* Approximate relationship: 1ex ≈ 0.5em in many fonts */
cap — cap height unit

1cap equals the height of uppercase letters (the cap height) in the current font. Useful for sizing decorative elements that should visually align with headings:

CSS
/* A vertical rule that matches the exact height of a heading */
.section-header {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.section-header::before {
  content: "";
  display: block;
  width: 4px;
  height: 1cap;        /* exactly as tall as the capitalised letters */
  background: #0066cc;
  border-radius: 2px;
}

/* Icon that matches the visual size of adjacent uppercase text */
.label-icon {
  width: 1cap;
  height: 1cap;
}
lh and rlh — line height units

CSS
/* lh = computed line-height of the current element */
.pull-quote {
  margin-block: 1lh; /* vertical margin equals exactly one text line */
}

/* rlh = computed line-height of the root element */
:root { line-height: 1.5; font-size: 16px; }
/* rlh = 24px */

.section {
  padding-block: 2rlh; /* top/bottom padding = 2 root line-heights = 48px */
}

/* Keeps spacing grid-aligned — everything is a multiple of the line height */
Practical use: the perfect prose column

Combining ch for line length with ex for vertical rhythm creates typography that adapts to the typeface:

CSS
/* A typography block that adapts to any serif or sans-serif font */
.prose {
  max-width: 65ch;         /* comfortable reading width in any font */
  font-size: 1.125rem;
  line-height: 1.7;
  margin-inline: auto;
}

.prose h2 {
  margin-top: 2lh;         /* two lines of space before each heading */
  margin-bottom: 0.5lh;    /* half a line after */
}

.prose p + p {
  margin-top: 0;           /* no extra gap between consecutive paragraphs */
}

.prose p {
  margin-bottom: 1lh;      /* one full line between paragraphs */
}
Next
The CSS math functions that make dynamic, responsive values possible: [CSS Functions (calc, min, max, clamp)](/css/css-functions).