text-box-trim: Buttons vertikal sauber zentrieren

Du kennst das: Ein Button mit padding-block: 10px – Text sollte perfekt mittig sitzen. Tut er aber nicht. Er wirkt einen Tick zu tief, und kein Auge täuscht sich da. Schuld ist nicht dein CSS, sondern die Font-Metrik selbst.

Warum Text in Buttons nie wirklich zentriert ist

Jede Schrift reserviert oberhalb der Cap-Height Platz für Akzente und Oberlängen. Unterhalb der Baseline kommt nochmal Raum für Unterlängen (g, y, p) dazu. Diese unsichtbaren Bereiche gehören zum Line-Box-Modell und zählen bei der Zentrierung mit – obwohl sie optisch leer sind.

Das Ergebnis: Die geometrische Mitte der Textzeile liegt nicht dort, wo das Auge die Mitte erwartet. Bei Button-Labels wie „Primary button“ ohne Unterlängen wird das besonders deutlich, weil der untere Weißraum ungenutzt bleibt.

Jahrelang war die einzige Lösung asymmetrisches Padding – oben ein paar Pixel mehr, unten weniger. Funktioniert, ist aber Font-abhängig und muss bei jedem Font-Wechsel neu justiert werden.

Die saubere Lösung: text-box-trim

Seit 2024 gibt es in Chrome und Safari die CSS-Property text-box-trim. Sie schneidet genau diese Font-Metrik-Überhänge ab und lässt nur den sichtbaren Glyph-Bereich übrig.

.button {
	text-box: trim-both cap alphabetic;
	line-height: 1;
	padding-block: 10px;
}

Was passiert hier: trim-both trimmt oben und unten. cap alphabetic legt fest, dass die obere Kante an der Cap-Height endet und die untere an der alphabetischen Baseline. Damit sitzt der Text endlich dort, wo das Auge ihn erwartet – und zwar Font-unabhängig.

Der Fallback für ältere Browser

Aktuell liegt der Browser-Support bei rund 85 Prozent. Für alle anderen brauchst du einen Fallback – und den baust du am saubersten mit @supports:

.button {
	display: inline-block;
	padding-block: 11px 9px;
	line-height: 1.2;
}

@supports (text-box: trim-both cap alphabetic) {
	.button {
		text-box: trim-both cap alphabetic;
		padding-block: 10px;
		line-height: 1;
	}
}

Browser ohne Support ignorieren den @supports-Block komplett und nehmen das asymmetrische Padding mit 11px 9px. Browser mit Support überschreiben die Werte und aktivieren text-box-trim. Kein JavaScript, keine Feature-Detection-Bibliothek – reines CSS.

Variante mit Custom Properties

Wenn du mehrere Button-Varianten hast (Primary, Secondary, Ghost) und nicht jedes Mal den kompletten Block wiederholen willst, lohnen sich Custom Properties:

:root {
	--btn-padding-top: 11px;
	--btn-padding-bottom: 9px;
}

@supports (text-box: trim-both cap alphabetic) {
	:root {
		--btn-padding-top: 10px;
		--btn-padding-bottom: 10px;
	}
}

.button {
	padding-block: var(--btn-padding-top) var(--btn-padding-bottom);
	line-height: 1.2;
}

@supports (text-box: trim-both cap alphabetic) {
	.button {
		text-box: trim-both cap alphabetic;
		line-height: 1;
	}
}

So steuerst du die Paddings zentral und musst bei Font-Wechseln nur eine Stelle anfassen.

Warum nicht einfach line-height: 1?

line-height: 1 wird oft als schneller Fix empfohlen – und hilft tatsächlich, weil es den Line-Box-Überhang reduziert. Aber es löst das Problem nur teilweise: Die Font-Metrik-Reserven oberhalb und unterhalb der Glyphen bleiben, nur eben mit weniger Puffer drumherum.

text-box-trim entfernt den Überhang an der Quelle. Kombinierst du beides, bekommst du das sauberste Ergebnis – vor allem bei Fonts mit ausgeprägten Oberlängen.

Fazit

text-box-trim ist eine dieser kleinen Properties, die ein jahrelang nerviges Problem endgültig erledigen. Mit @supports als Fallback kannst du es heute schon produktiv einsetzen, ohne ältere Browser zu brechen. Die zwei Zeilen Extra-CSS lohnen sich für jedes Button-System.