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 line box. The line box is taller than the capital letters. It extends above the tallest capital (cap height) and below the baseline. This extra space is called half-leading: the internal padding added above and below the text within the line-height.
Even at line-height: 1, a font's ascender 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
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.
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 progressive enhancement. 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;
}