Überschriften ohne Schusterjungen: text-wrap: balance
Eine Überschrift, bei der das letzte Wort allein in der zweiten Zeile steht, sieht billig aus. Zwei CSS-Zeilen räumen das auf — ohne JavaScript und ohne manuelle Zeilenumbrüche.
Du kennst das: Die Überschrift passt auf dem Desktop wunderbar in eine Zeile, und auf dem Tablet steht plötzlich ein einzelnes Wort allein in Zeile zwei. In der Typografie heißt so etwas Schusterjunge, und es sieht immer nach Versehen aus — nie nach Absicht.
Früher habe ich das mit <br> an der „richtigen" Stelle erschlagen. Funktioniert genau bei einer Bildschirmbreite und ist bei jeder anderen falsch. Heute macht der Browser das selbst:
h1, h2, h3 {
text-wrap: balance;
}Das war's. Der Browser verteilt die Wörter so auf die Zeilen, dass sie möglichst gleich lang werden — statt jede Zeile bis zum Anschlag zu füllen und den Rest fallen zu lassen.
Wo du es einsetzt — und wo nicht
balance ist absichtlich teuer: Der Browser muss mehrere Umbruch-Varianten durchrechnen. Deshalb wenden ihn die Engines nur auf kurze Blöcke an (Chrome und Safari bis etwa sechs Zeilen, darüber fällt es still auf normales Umbrechen zurück). Genau richtig für Überschriften, Buttons, Karten-Titel, Bildunterschriften. Nicht für Fließtext.
Für lange Absätze gibt es den Geschwister-Wert:
p {
text-wrap: pretty;
}pretty balanciert nicht, sondern kümmert sich nur um die letzte Zeile: Es verhindert, dass ein Absatz mit einem einsamen Wort endet. Das ist billig genug für laufenden Text.
Ein vollständiges Beispiel
/* Überschriften: gleichmäßig verteilte Zeilen */
h1, h2, h3, .card-title {
text-wrap: balance;
/* Sinnvolle Obergrenze — sonst balanciert der Browser über die halbe Seite */
max-inline-size: 28ch;
}
/* Fließtext: nur die letzte Zeile absichern */
p, li {
text-wrap: pretty;
hyphens: auto; /* zusammen mit lang="de" im <html> */
}Das max-inline-size: 28ch ist der Teil, den ich am längsten übersehen habe. balance verteilt auf die verfügbare Breite — wenn die Überschrift über 1400 Pixel laufen darf, entsteht eine gleichmäßig verteilte, aber trotzdem unlesbar breite Zeile. Erst die Zeilenlängen-Bremse macht daraus Typografie.
Muss ich einen Fallback bauen?
Nein. Ältere Browser kennen den Wert nicht und ignorieren die Deklaration — der Text bricht dann eben um wie immer. Es gibt nichts, was kaputtgehen kann, und deshalb auch keinen Grund, es hinter einem @supports zu verstecken.
Ich setze die beiden Regeln inzwischen in jedem Projekt ins Basis-Stylesheet. Zwei Zeilen, die man einmal schreibt und danach nie wieder anfasst — und die auf jeder Kundenseite den Unterschied zwischen „selbst gebastelt" und „gesetzt" ausmachen.
Wenn du eine Website hast, bei der genau solche Kleinigkeiten fehlen: Ich baue Seiten mit eigenem CMS, bei denen der Text vom Kunden kommt und die Typografie trotzdem sitzt. Schreib mir über bymw.de.
Quellen
Du brauchst mehr als ein Snippet?
Ich entwickle Android-Apps in Kotlin und moderne Websites für Selbstständige und kleine Unternehmen — von der ersten Idee bis zum Release.
Projekt anfragen →Verwandte Snippets
subgrid – Karten, deren Zeilen wirklich auf einer Linie liegen
Drei Karten nebeneinander, jede mit Titel, Text und Knopf – und alles steht leicht versetzt, weil ein Titel zweizeilig ist. Mit subgrid teilen sich die Karten die Zeilen des Eltern-Grids, und alles sitzt bündig. Ohne feste Höhen, ohne JavaScript.
accent-color – Checkboxen und Regler in deiner Markenfarbe, in einer Zeile
Checkboxen und Radiobuttons waren jahrelang der Grund, warum Leute sie mit appearance: none nachgebaut haben – und dabei die Tastaturbedienung verloren. Eine einzige CSS-Eigenschaft macht das überflüssig.
Verschachteltes CSS – ganz ohne Sass, direkt im Browser
Das Feature, für das die meisten Leute überhaupt erst einen CSS-Präprozessor eingerichtet haben, kann der Browser inzwischen selbst. Kein Build-Schritt, keine Abhängigkeit – nur ein paar Regeln, die man kennen sollte.