Alle Beiträge

Schrift, die mitwächst: responsive Schriftgrößen ohne Sprünge

Auf dem Tablet war die Überschrift in der Karte fast so groß wie der Sektionskopf darüber. Schuld waren feste Pixel und zwei Medienabfragen. Wie wir unsere eigene Seite auf rem und clamp() umgebaut haben, mit den gemessenen Werten davor und danach.

Dieselbe Überschrift in drei Gerätebreiten nebeneinander, jedes Mal im richtigen Verhältnis zur Zeile darüber

Es fällt selten beim Bauen auf, sondern später, wenn jemand die Seite auf dem Tablet aufmacht. Die Überschrift über einer Karte steht dort fast so groß da wie der Sektionskopf darüber. Auf dem Telefon liegt die kleine Zeile über einer Überschrift plötzlich fast gleichauf mit ihr. Am Rechner stimmt alles.

Genau das hatten wir auf dieser Seite. Nachgemessen, nicht geschätzt, bei 1440, 900 und 375 Pixeln Fensterbreite:

Element Rechner Tablet Telefon
Überschrift im Einstieg 66 px 44 px 34 px
Sektionskopf 46 px 38 px 30 px
Überschrift in einer Karte 32 px 32 px 26 px
Zeile über dem Sektionskopf 17 px 17 px 17 px

In der letzten Zeile steht der Fehler. Die kleine Zeile über einer Überschrift, bei uns steht dort „Kundenprojekte", war bei jeder Breite 17 Pixel groß. Die Überschrift daneben fiel von 46 auf 30. Am Rechner war die eine also 2,7 mal so groß wie die andere, auf dem Telefon nur noch 1,8 mal. Der Abstand, der beide als Beschriftung und Überschrift unterscheidbar macht, war zur Hälfte weg.

Die dritte Zeile ist derselbe Fehler in der anderen Richtung: Die Überschrift in der Karte blieb bei 32 Pixeln stehen, während der Sektionskopf darüber auf 38 fiel. Bei 768 Pixeln Fensterbreite standen beide fast gleichauf, obwohl die eine der anderen untergeordnet ist.

Warum das passiert

Zwei Gewohnheiten zusammen erzeugen es zuverlässig.

Alles steht in Pixeln. Auf unserer Seite waren es 183 Angaben, jede einzelne in px, keine in rem, keine in clamp().

Die Größe ändert sich an Medienabfragen. Bei uns an zweien, 1100 und 720 Pixel. Zwischen den Sprüngen passiert nichts.

Das führt dazu, dass jede Überschrift ihre Stufen einzeln braucht: eine für den Rechner, eine ab 1100, eine ab 720. Wer eine vergisst, merkt es nicht, weil die Seite ja nicht kaputt aussieht. Sie sieht nur an einer Breite falsch aus, die man beim Bauen nicht offen hat. Bei uns fehlten die Stufen bei der Karte und bei der Beschriftung, und genau die zwei fielen auf.

Der heutige Stand der Technik

Die kurze Fassung, und sie ist tatsächlich so kurz:

  1. rem als Grundmaß. Damit folgt die Schrift der Einstellung des Browsers.
  2. clamp() für alles, was groß ist. Damit wächst sie stufenlos mit der Fensterbreite, statt zu springen.
  3. vw nur als Mittelteil, nie allein. Der Boden und die Decke stehen in rem.

Der dritte Punkt ist der, der am häufigsten falsch gemacht wird, deshalb zuerst.

Warum reines vw nicht geht

font-size: 4vw klingt nach der einfachsten Lösung für flüssige Typografie. Sie ist aber nicht barrierefrei, und der Grund ist unangenehm elegant:

Wenn jemand eine Seite im Browser auf 200 Prozent vergrößert, wächst das CSS-Pixel. Ein Fenster, das vorher 1400 CSS-Pixel breit war, ist danach 700 breit. Und 4vw von 700 ist genau die Hälfte von 4vw von 1400.

Die Vergrößerung und die Verkleinerung heben sich exakt auf. Der Text steht nach dem Zoomen genauso groß da wie vorher. Wer schlecht sieht und deshalb zoomt, hat nichts gewonnen. Das ist ein Verstoß gegen WCAG-Kriterium 1.4.4, das verlangt, dass sich Text auf 200 Prozent vergrößern lässt, ohne dass Inhalt verloren geht.

Innerhalb von clamp() ist vw dagegen harmlos, solange Boden und Decke in rem stehen: Beim Zoomen wachsen die beiden, und die Schrift landet auf dem Boden statt im Nichts.

Warum px die Browser-Einstellung ignoriert

Der zweite Punkt, der leicht untergeht: font-size: 17px bleiben 17 Pixel, auch wenn jemand im Browser unter „Darstellung" die Schriftgröße auf „groß" oder „sehr groß" stellt. Diese Einstellung verändert nur den Bezugswert von rem, und den fragt ein Pixelwert nie.

Das betrifft nicht wenige. Es ist die Einstellung, die Leute benutzen, bevor sie merken, dass es Zoom gibt, und die viele dauerhaft anlassen. Auf einer Seite, die durchgehend in Pixeln rechnet, hat sie keine einzige Wirkung.

Der Umbau dafür ist klein: Auf html kommt keine Schriftgröße, damit die Vorgabe des Browsers stehen bleibt, und alles andere teilt man durch 16. Aus 17 px wird 1.0625rem.

clamp() in einem Satz

font-size: clamp(2.75rem, 2.3333rem + 1.8519vw, 4rem);

Drei Werte: Boden, flüssiger Teil, Decke. Der Browser nimmt den mittleren Wert und lässt ihn nicht unter den ersten und nicht über den dritten.

Der mittlere Teil ist eine Geradengleichung, und man kann sie ausrechnen statt zu probieren. Wer will, dass eine Schrift bei 360 Pixeln Fensterbreite min groß ist und bei 1440 max:

Steigung  = (max - min) / (1440 - 360)
vw-Anteil = Steigung * 100
rem-Anteil = (min - Steigung * 360) / 16

Für 44 bis 64 Pixel ergibt das die Zeile oben. Es gibt Rechner im Netz, die das abnehmen, aber die drei Zeilen sind schneller getippt als eine Seite geöffnet.

Der flüssige Teil braucht immer einen rem-Anteil. Eine reine vw-Mitte kippt beim Zoomen in den Boden, und dann hat man die Sprünge wieder, nur an einer anderen Stelle.

Ein Maßstab statt einer Liste

Damit ist die Technik erledigt. Das eigentliche Problem war die Ordnung.

Unsere 183 Angaben liefen auf 36 verschiedene Werte hinaus, und viele davon lagen einen halben Pixel auseinander: 17,5 und 17 und 16,5. Kein Mensch hat je entschieden, dass diese drei drei verschiedene Dinge sind. Sie sind entstanden.

Daraus haben wir elf Stufen gemacht, eine geometrische Reihe mit dem Faktor 1,13. Jede Stufe ist das 1,13-fache der nächstkleineren, am Telefon wie am Rechner. Das ist der Punkt: Wenn alle Stufen mit derselben Kurve wachsen, bleibt das Verhältnis zweier Überschriften bei jeder Breite dasselbe, und die Rangfolge hält vom Telefon bis zum Rechner durch.

Der Nebeneffekt war die eigentliche Überraschung: Keine Überschrift hat sich am Rechner um mehr als 1,5 Pixel bewegt. Die Werte lagen ohnehin nah an einer sauberen Reihe, sie waren nur nie als eine gedacht. Was sich verändert hat, liegt alles unterhalb der Rechnerbreite.

Dieselbe Tabelle wie oben, jetzt danach:

Element Rechner Tablet Telefon
Überschrift im Einstieg 64 px 54 px 44,3 px
Sektionskopf 44,5 px 38,5 px 32,7 px
Überschrift in einer Karte 31 px 27,7 px 24,6 px
Zeile über dem Sektionskopf 17 px 16 px 15 px

Das Verhältnis von Sektionskopf zu Beschriftung liegt jetzt am Rechner bei 2,6 und auf dem Telefon bei 2,2 statt bei 1,8. Und die Karte steht wieder eine Stufe unter dem Sektionskopf, an jeder Breite.

Was nicht mitwachsen darf

Eine Sache, die in vielen Anleitungen fehlt: Fließtext gehört nicht in den flüssigen Teil.

Es ist verlockend, alles durch dieselbe Formel zu schicken. Das Ergebnis ist aber, dass der Text auf dem Telefon kleiner wird, also genau dort, wo am wenigsten Platz ist und am ungünstigsten gelesen wird. Unsere Lesegrößen stehen deshalb fest, nur eben in rem statt in px: Ein Absatz ist auf dem Telefon genauso groß wie am Rechner.

Flüssig sind bei uns nur die Überschriften, die Einleitung darunter und die Beschriftung darüber. Alles andere hat einen Wert.

Dazu ein zweiter Boden, den wir vorher nicht hatten: In den Karten des Einstiegs stand die Schrift in cqw, also relativ zur Breite ihrer eigenen Karte. Das ist die richtige Einheit dafür, aber sie hat weder unten noch oben eine Grenze. Eine der Kennungen kam dadurch bei voller Fensterbreite auf 10,5 Pixel heraus. Containereinheiten sind großartig, sie brauchen aber genau wie vw ein clamp() um sich herum.

Nebenbei: Grau ist keine Farbe für Kleinschrift

Beim Nachmessen fiel noch etwas auf, das mit Größe zusammenhängt. Die Zeile unter einem Beitragstitel, „06.08.2026 · 12 Min. Lesezeit · von Ronny Arndt", stand in einem Grau mit 5,5 : 1 Kontrast. Das erfüllt die Norm, sie verlangt 4,5 : 1.

Lesbar war sie trotzdem kaum, und der Grund ist die Kombination: 12,5 Pixel, Versalien, weite Laufweite. Versalien bestehen fast nur aus dünnen Senkrechten, und bei kleinem Grad und mageren Strichen bleibt zu wenig Farbe auf der Fläche. Der Kontrastwert misst zwei Farbflächen gegeneinander, nicht wie viel Fläche der Buchstabe überhaupt hat.

Drei Änderungen, jede für sich klein:

  • Grau von 5,5 : 1 auf 8,5 : 1
  • alle Kleinstschriften der Seite auf einen Wert statt 12,5 / 13 / 13,5
  • Versalien in Kleinschrift auf halbfett statt mager

Die Norm ist ein Boden, kein Ziel. Wer 4,5 : 1 trifft und die Sache damit für erledigt hält, baut Seiten, die auf einem hellen Bildschirm im Tageslicht nicht funktionieren.

Wie man das nachprüft

Ohne Messung ist das alles Geschmack. Drei Wege, die nichts kosten:

  1. Die Entwicklerwerkzeuge auf verschiedene Breiten stellen und die berechnete Schriftgröße ablesen, nicht die im Stylesheet. Interessant sind die Breiten zwischen den Geräten: 900, 1024, 1180. Dort liegen die Fehler.
  2. Im Browser die Schriftgröße auf „sehr groß" stellen. Ändert sich nichts, steht die Seite in Pixeln.
  3. Auf 200 Prozent zoomen und prüfen, ob die Überschriften mitgehen. Bleiben sie stehen, steckt irgendwo reines vw.

Bei uns lief der zweite und der dritte Punkt vor dem Umbau ins Leere. Das ist der unangenehme Teil daran: Man sieht es nicht, solange man nicht danach sucht.

Wenn du wissen willst, wie deine Seite zwischen den Gerätebreiten dasteht: Schreib uns kurz. Wir messen die Überschriften an sechs Breiten durch und schicken dir die Tabelle.

Quellen

Stand dieses Beitrags

Sprachlich überarbeitet. Die Messwerte im Beitrag gelten weiter.

Häufige Fragen zu responsiven Schriftgrößen

Sind Pixel für Schriftgrößen verboten?

Nein, und das ist ein verbreitetes Missverständnis. Pixel sind an vielen Stellen richtig: Rahmenstärken, Abstände in einem Bedienelement, alles, was nicht mit dem Text mitwachsen soll. Falsch sind sie dort, wo Schrift steht. Ein Wert in px folgt der Einstellung „Schriftgröße" im Browser nicht. Wer sie auf „sehr groß" stellt, weil er sonst schlecht liest, sieht auf einer reinen Pixelseite keinen einzigen Buchstaben mehr als vorher.

Was ist der Unterschied zwischen rem und em?

`rem` bezieht sich immer auf die Grundschrift des Dokuments, `em` auf die Schriftgröße des Elements, in dem der Wert steht. Damit vererbt sich `em` und multipliziert sich: Eine Liste mit `font-size: 0.9em` in einer Liste mit `font-size: 0.9em` landet bei 0,81. Für Schriftgrößen ist `rem` deshalb die ruhigere Wahl. Für Abstände, die zur Schrift des eigenen Elements passen sollen, ist `em` weiter richtig.

Warum nicht einfach font-size in vw angeben?

Weil die Schrift dann nicht mehr vergrößerbar ist. Wer eine Seite auf 200 Prozent zoomt, halbiert damit die Fensterbreite in CSS-Pixeln. Eine Angabe in reinem vw wird dabei genau so viel kleiner, wie der Zoom sie größer machen sollte, und der Text steht am Ende unverändert da. Das ist ein Verstoß gegen WCAG-Kriterium 1.4.4. Innerhalb von clamp() ist vw dagegen unbedenklich, weil der Boden und die Decke in rem stehen und den Zoom mitnehmen.

Wie viele Schriftgrade braucht eine Website?

Weniger, als von allein entstehen. Auf unserer Seite standen 183 Angaben mit 36 verschiedenen Werten, viele davon einen halben Pixel auseinander. Daraus sind elf Stufen für Überschriften und acht Lesegrößen geworden. Der Grundsatz dahinter: Wer eine neue Überschrift anlegt, nimmt eine vorhandene Stufe. Ein Zwischenwert ist immer ein Zeichen dafür, dass die Rangfolge nicht durchdacht ist.

Ab welcher Breite soll die Schrift mitwachsen?

Wir rechnen von 360 bis 1440 Pixeln Fensterbreite. Darunter greift der Boden, darüber die Decke. 360 ist die Breite, unter die im Bestand praktisch kein Gerät mehr fällt, 1440 die Breite, ab der eine Überschrift nicht weiter wachsen soll, weil sie sonst die Lesespalte sprengt. Wichtig ist vor allem die Decke: Ohne sie wird die Schrift auf einem 34-Zoll-Bildschirm absurd groß.