Entry 04

Label centered on its letters with text-box

Use it on single-line labels in buttons, badges and chips, so equal padding looks equal in any font.

Open
In the first button the sulphur box ends at the top of the capitals and at the baseline, so the padding round it is even and the descenders hang into it. The second has spare room above the capitals and under the baseline. The third is a flex container and is not trimmed. The fourth is a flex button with an icon, and its label is trimmed through the span. At normal size they are 35px, 48px, 48px and 40px tall.
Code CSS · 14 lines
.button {
  display: inline-block;
  padding: 0.75rem 1.25rem;
  text-box: trim-both cap alphabetic;
}

.button-with-icon {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.75rem 1.25rem;
}

.button-with-icon > span { text-box: trim-both cap alphabetic; }
Why it works, the rules and the credits 3 reasons · 5 rules · support · credits

Why it works

  1. A line of text reserves space above the capitals and below the baseline, and the two amounts differ from font to font. Equal padding around that line puts the letters off-center.
  2. trim-both cap alphabetic cuts the box down to the cap height and the baseline. The padding then starts at the letters.
  3. A font swap or a fallback font no longer moves the label.

Rules

  1. It does nothing on a flex or grid container. A button that is inline-flex because it holds an icon needs the declaration on the element that wraps the text, as in the second rule of the block.
  2. The button gets shorter, because the padding now starts at the letters. With 0.75rem of padding it went from 48px tall to 35px in Chrome and Safari. Raise the padding to keep the height.
  3. Use it for one line. Descenders hang into the bottom padding, which is the intent.
  4. Scope it to labels. Never set it on *, because it shrinks every text block. A one-line paragraph at 16px/1.5 went from 25px tall to 11px.
  5. Write no fallback. Without support the label keeps its normal line box.

Support

Chrome
133
Firefox
154
Safari
18.2

Credits

Borrowed from: Stripe, which ships it on its buttons at stripe.com. There the button is a flex container, so the declaration has no effect and uneven padding does the centering. The first rule above is the fix.

Docs: MDN: text-box