Skip to main content

14

Trim

Every font adds phantom space above capital letters and below the baseline. Your spacing tokens are fighting it. text-box-trim removes it.

6 min read

Your heading margin is 1.5em. The heading still looks closer to the section above it than to the content below. You increase the top margin. It helps, but the spacing never quite matches your design. The visual gap between the heading and the text below it is smaller than the gap you specified.

The problem isn't the margin. It's the line box.

How line boxes add phantom space

When a browser renders text, it wraps each line in a . The line box is taller than the capital letters. It extends above the tallest capital () and below the . This extra space is called : the internal padding added above and below the text within the line-height.

Even at line-height: 1, a font's metric typically exceeds the cap height by 15–30%. That excess space sits above your H or T, invisible, pushing the visual text downward from the element's top edge.

When you set margin-top: 1.5em on a heading, 1.5em of space is added above the element box, but the first visible ink doesn't start at the element box. It starts some distance below the top, after the phantom ascender space.

Text Box Trim

New

Spacing that matches what you specified

The dashed border shows the element box. Without trim, invisible ascender space above the capital S separates the ink from the border. With trim, the element box starts at the cap height.

default line box — phantom space above cap height

Toggle to trimmed. The dashed border moves flush with the top of the capital letter — the phantom ascender space above "S" disappears. The badge pill also tightens: without trim it's taller than the cap height, with trim it wraps the text precisely. Both require the same two properties.

The Rule

Set text-box-trim: trim-both and text-box-edge: cap alphabetic on headings and labels where vertical alignment matters.

h1, h2, h3,
.label,
.badge-text {
text-box-trim: trim-both;
text-box-edge: cap alphabetic;
}
h1, h2, h3,
.label,
.badge-text {
text-box-trim: trim-both;
text-box-edge: cap alphabetic;
}

text-box-trim: trim-both removes the space above and below the text content. text-box-edge: cap alphabetic tells the browser where to trim: flush with the top of capital letters (cap) and flush with the alphabetic baseline (alphabetic, which sits at the bottom of most lowercase letters).

After trimming, margin-top: 1.5em places the visual ink 1.5em from the previous element's last baseline. The spacing you specify becomes the spacing you see.

Shorthand

Chrome 133+ and Safari 18.4+ accept the shorthand text-box:

h1, h2, h3 {
text-box: trim-both cap alphabetic;
}
h1, h2, h3 {
text-box: trim-both cap alphabetic;
}

Use the longhand form for now. Support for the shorthand is newer.

When to use it

Trim is most valuable on:

  • Headings with specified margin tokens, where you want exact optical spacing
  • Badge and label text, where the phantom ascender space makes the label look taller than its background
  • Button text, where the ascender space makes the label look vertically off-center

It's less useful on body paragraphs, where the full line box contributes to line-height rhythm. Trimming mid-paragraph would collapse the space between lines.

Common Mistake

Applying text-box-trim to p or li elements inside a line-height: 1.6 prose block. Trim removes the space the line-height uses for vertical rhythm, and paragraphs collapse.

Browser support

text-box-trim and text-box-edge are supported in Chrome 133+ and Safari 18.4+. Firefox has not shipped support as of mid-2026.

This is a . Browsers that don't support it render the original line box. The spacing looks slightly off, which is the same as it looked before you knew this property existed.

h1 {
/* Spacing without trim — works everywhere */
margin-top: 2rem;

/* With trim: spacing aligns to cap height */
text-box-trim: trim-both;
text-box-edge: cap alphabetic;
}
h1 {
/* Spacing without trim — works everywhere */
margin-top: 2rem;

/* With trim: spacing aligns to cap height */
text-box-trim: trim-both;
text-box-edge: cap alphabetic;
}