CSS: Grundlagen

CSS-Schriftart festlegen: Größe, Stärke und Zeilenabstand

Die Schriftart legst du mit font-family fest und nennst dahinter Ersatzschriften bis zu einer generischen Familie wie sans-serif. Die Größe gehört in rem, damit die Browsereinstellung wirkt. Der Zeilenabstand steht als Zahl ohne Einheit, für Fließtext bei mindestens 1,5.

Schrift ist der Teil des Stylesheets, der über Lesbarkeit entscheidet. Vier Angaben bestimmen den größten Teil davon: die Schriftfamilie, die Schriftgröße, die Zeilenhöhe und die Zeilenlänge. Alle vier sind in wenigen Zeilen gesetzt, und alle vier stehen in direkter Verbindung zu Anforderungen der WCAG.

Diese Seite gehört zur CSS-Referenz für zugängliche Websites. Sie behandelt die Auswahl und die Einstellung der Schrift. Wie eine eigene Schriftdatei mit @font-face in das Dokument kommt und warum Google Fonts auf den eigenen Server gehören, steht unter CSS einbinden. Stand September 2026 arbeiten alle aktuellen Browser nach dem CSS Fonts Module Level 4 des W3C.

Das Wichtigste in Kürze

  • font-family nimmt eine Liste. Der Browser nimmt die erste Schrift, die er findet. Am Ende steht immer eine generische Familie wie sans-serif oder serif.
  • Die Schriftgröße gehört in rem. Eine Basis in Pixeln am html-Element hebelt die Grundschriftgröße aus, die Nutzende im Browser eingestellt haben.
  • line-height steht ohne Einheit, etwa 1.6. Mit Einheit vererbt sich der berechnete Wert, und Überschriften bekommen den Zeilenabstand des Fließtextes.
  • WCAG 1.4.12 Textabstände nennt vier Werte, die ohne Inhaltsverlust möglich sein müssen: Zeilenhöhe 1,5, Absatzabstand 2em, Laufweite 0,12em, Wortabstand 0,16em.
  • Eine Zeile liest sich zwischen 45 und 75 Zeichen am besten. Die Einheit ch setzt das direkt um, etwa mit max-width: 65ch.
  • Schriftgrößen allein in vw verstoßen gegen 1.4.4 Textgröße ändern, weil der Text beim Zoomen seine Größe behält. Ein rem-Anteil in clamp() löst das.

CSS-Schriftart festlegen: font-family und der Font-Stack

font-family nimmt eine durch Kommas getrennte Liste. Der Browser prüft sie von links nach rechts und nimmt die erste Schrift, die auf dem System vorhanden oder als Webfont geladen ist.

body {
  font-family: "Source Sans 3", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

code, pre {
  font-family: ui-monospace, "SF Mono", "Cascadia Code", Consolas, monospace;
}

Namen mit Leerzeichen gehören in Anführungszeichen. Am Ende der Liste steht eine generische Familie, damit der Browser im Notfall wenigstens die richtige Gattung wählt.

Generische Familie Bedeutung
sans-serif serifenlose Schrift, Standard für Bildschirmtext
serif Schrift mit Serifen
monospace dicktengleiche Schrift für Code
system-ui die Oberflächenschrift des Betriebssystems
ui-monospace die dicktengleiche Systemschrift
cursive, fantasy Schreibschrift und Zierschrift, für Fließtext ungeeignet

Der Systemschrift-Stack aus dem Beispiel oben lädt keine einzige Datei. Auf macOS erscheint San Francisco, auf Windows Segoe UI, auf Android Roboto. Das spart den Ladevorgang und den Layoutsprung beim Schriftwechsel. Ich halte diesen Weg für die beste Vorgabe, solange die Marke keine eigene Schrift verlangt.

font-family vererbt sich an alle Nachfahren. Eine Angabe am body genügt für das ganze Dokument. Ausgenommen sind Formularelemente, weil Browser ihnen eine eigene Schrift geben.

input, button, select, textarea {
  font: inherit; /* ohne diese Zeile erscheinen Felder in der Browserschrift */
}

Schriftgröße: rem, em, px und clamp

Vier Einheiten kommen für font-size in Frage. Sie unterscheiden sich darin, worauf sie sich beziehen.

Einheit Bezug Geeignet für
rem Schriftgröße des html-Elements Fließtext, Überschriften, Abstände
em Schriftgröße des eigenen Elements Abstände innerhalb einer Komponente
px feste Bildschirmeinheit Haarlinien und Rahmen
% Schriftgröße des Elternelements Stufen in verschachtelten Listen

Der Ausgangswert von rem ist die Grundschriftgröße des Browsers. Sie liegt bei 16 Pixeln und ist in den Einstellungen jedes Browsers änderbar. Genau diese Einstellung geht verloren, sobald ein Stylesheet sie überschreibt.

/* Don't: die Einstellung im Browser bleibt wirkungslos */
html { font-size: 16px; }

/* Do: nichts setzen, die Größen darunter in rem angeben */
body { font-size: 1rem; }
h1   { font-size: 2.5rem; }

Bei em addiert sich die Verschachtelung. Eine Liste mit font-size: 0.9em in einer Liste mit font-size: 0.9em landet bei 0,81 und danach bei 0,73. Für Schriftgrößen ist rem deshalb die ruhigere Wahl. Für Abstände innerhalb einer Komponente ist em genau richtig, weil padding: 0.5em 1em mit der Schriftgröße mitwächst.

Fließende Größen mit clamp()

clamp() nimmt einen Mindestwert, einen Wunschwert und einen Höchstwert. Überschriften wachsen damit mit dem Viewport, ohne dass eine Media Query nötig wird.

h1 {
  /* Don't: der Text behält beim Zoomen seine Größe */
  font-size: 5vw;
}

h1 {
  /* Do: der rem-Anteil sorgt dafür, dass Zoom und Textgröße wirken */
  font-size: clamp(1.75rem, 1.25rem + 2.5vw, 3rem);
}

Der Unterschied ist mehr als Geschmack. Eine Größe allein in vw bezieht sich auf die Viewport-Breite in CSS-Pixeln. Beim Zoomen schrumpft diese Breite in genau dem Maß, in dem der Browser vergrößert. Der Text bleibt dadurch gleich groß, und die Anforderung aus 1.4.4 ist verfehlt. Sobald ein Anteil in rem in der Rechnung steht, wächst der Text wieder mit.

Schriftstärke und Schriftschnitte

font-weight nimmt Zahlen von 1 bis 1000 sowie die Schlüsselwörter normal (400) und bold (700). Wirksam sind nur die Werte, für die ein Schnitt vorliegt.

.lauftext { font-weight: 400; }
.betont   { font-weight: 600; }

Fehlt der passende Schnitt, rechnet der Browser einen künstlichen aus. Diese Fälschung verdickt die Buchstaben, ohne die Formen zu ändern, und sieht bei kleinen Größen schmierig aus. font-synthesis schaltet das ab.

body { font-synthesis: none; } /* keine gefälschten Fett- und Kursivschnitte */

Variable Schriften lösen das Problem an der Wurzel. Eine einzige Datei enthält den gesamten Bereich einer Achse, etwa alle Stärken von 100 bis 900. Das spart Anfragen und macht jede Zwischenstufe verfügbar.

@font-face {
  font-family: "Inter var";
  src: url("/fonts/inter-variable.woff2") format("woff2-variations");
  font-weight: 100 900; /* der gesamte Bereich aus einer Datei */
}

Zeilenabstand, Absatzabstand und Zeilenlänge

line-height gehört ohne Einheit notiert. Der Wert ist dann ein Faktor der jeweiligen Schriftgröße und vererbt sich als Faktor weiter.

/* Don't: Kinder erben 24px, auch wenn ihre Schrift 40px groß ist */
body { font-size: 1rem; line-height: 24px; }

/* Do: jedes Element rechnet den Abstand aus seiner eigenen Größe */
body { line-height: 1.6; }
h1, h2, h3 { line-height: 1.2; }

Große Schrift benötigt anteilig weniger Zeilenabstand. Für Fließtext liegt ein guter Wert zwischen 1,5 und 1,7, für Überschriften zwischen 1,1 und 1,3.

Die Zeilenlänge steuerst du über die Breite des Textblocks. Die Einheit ch entspricht der Breite der Ziffer Null in der aktuellen Schrift und bildet Zeichen pro Zeile gut ab.

.prose {
  max-width: 65ch;    /* rund 65 Zeichen je Zeile */
  line-height: 1.6;
  margin-inline: auto;
}

.prose p + p {
  margin-block-start: 1.5em; /* Absatzabstand relativ zur Schriftgröße */
}

Zeilen über 90 Zeichen kosten beim Zeilenwechsel Zeit, weil das Auge den Anfang der nächsten Zeile suchen muss. Sehr kurze Zeilen unter 40 Zeichen zerreißen den Satz. Der Korridor von 45 bis 75 Zeichen stammt aus der Typografie und hat sich am Bildschirm bestätigt.

Wenn die Ersatzschrift springt

Zwischen dem ersten Aufbau der Seite und dem Eintreffen des Webfonts zeigt der Browser die Ersatzschrift. Unterscheiden sich beide in der Höhe der Kleinbuchstaben oder in der Laufweite, verschiebt sich beim Austausch der gesamte Text. Diese Verschiebung zählt in die Bewertung der Core Web Vitals ein und stört beim Lesen.

Vier Deskriptoren gleichen die Ersatzschrift an die eigentliche Schrift an. Sie stehen in einer zweiten @font-face-Regel, die allein den Ersatz beschreibt.

@font-face {
  font-family: "Inter Fallback";
  src: local("Arial");
  size-adjust: 107%;        /* skaliert die Ersatzschrift */
  ascent-override: 90%;     /* Oberlänge */
  descent-override: 22%;    /* Unterlänge */
  line-gap-override: 0%;
}

body { font-family: "Inter", "Inter Fallback", sans-serif; }

Für Tabellen mit Zahlen hilft eine weitere Angabe. Mit font-variant-numeric: tabular-nums bekommt jede Ziffer dieselbe Breite, und die Spalten stehen untereinander.

td.betrag { font-variant-numeric: tabular-nums; text-align: end; }

Textsatz: Umbruch, Trennung und Ausrichtung

Vier Eigenschaften bestimmen, wie eine Zeile endet.

.prose {
  hyphens: auto;             /* Silbentrennung nach den Regeln der Sprache */
  overflow-wrap: break-word; /* lange URLs umbrechen statt überstehen */
  text-align: start;         /* Flattersatz, kein Blocksatz */
}

h2 {
  text-wrap: balance;        /* verteilt die Wörter gleichmäßig auf die Zeilen */
}

hyphens: auto setzt ein korrektes lang-Attribut am <html>-Element voraus. Ohne lang="de" kennt der Browser die Trennregeln nicht und trennt gar nicht. Wie das Attribut gesetzt wird, steht unter Dokument-Metadaten im head.

text-wrap: balance arbeitet in allen aktuellen Browsern und gleicht die Zeilen kurzer Blöcke aus, etwa bei Überschriften. Für Fließtext ist text-wrap: pretty gedacht, das vor allem einzelne Wörter in der letzten Zeile verhindert. Browser ohne Unterstützung ignorieren den Wert folgenlos.

Bei text-transform: uppercase ändert sich allein die Darstellung. Der Screenreader liest den Text aus dem Quelltext und damit die übliche Schreibweise. Stehen die Versalien dagegen im HTML, buchstabieren manche Screenreader kurze Wörter als Abkürzung. Versalien gehören deshalb ins Stylesheet, und auch dort sparsam, weil sie langsamer zu lesen sind.

Barrierefreiheit: worauf es ankommt

200 Prozent Vergrößerung ohne Verlust

1.4.4 Textgröße ändern verlangt, dass Text sich auf 200 Prozent vergrößern lässt, ohne dass Inhalt oder Funktion verloren gehen. Drei Muster stehen dem im Weg: Schriftgrößen allein in vw, feste Höhen an Textcontainern und overflow: hidden an einer Box mit fester Höhe. Die beiden letzten Fälle beschreibt die Seite zu overflow.

Der Prüfweg dauert eine Minute. Stelle die Zoomstufe des Browsers auf 200 Prozent und lies die Seite. Stelle danach in den Browsereinstellungen die Grundschriftgröße auf 24 Pixel und lade neu. Bleibt die Seite unverändert, steht irgendwo eine Pixelgröße am html-Element.

Die vier Werte aus 1.4.12 Textabstände

1.4.12 Textabstände verlangt, dass der Inhalt vier Anpassungen verkraftet, ohne dass etwas verschwindet oder sich überlappt.

Angabe Geforderter Wert
Zeilenhöhe mindestens das 1,5-Fache der Schriftgröße
Abstand nach einem Absatz mindestens das 2-Fache der Schriftgröße
Laufweite zwischen Zeichen mindestens das 0,12-Fache der Schriftgröße
Wortabstand mindestens das 0,16-Fache der Schriftgröße

Zum Prüfen fügst du diese Regel in den Entwicklerwerkzeugen ein und sieht nach, was zerfällt:

* {
  line-height: 1.5 !important;
  letter-spacing: 0.12em !important;
  word-spacing: 0.16em !important;
}
p { margin-block-end: 2em !important; }

Wer die Werte von vornherein einhält, hat an dieser Stelle nichts zu tun. Der übliche Befund sind Schaltflächen mit fester Höhe und Navigationsleisten, deren Einträge in eine zweite Zeile rutschen und dort abgeschnitten werden. Den vollständigen Testweg beschreibt Reflow, Zoom und Textabstände.

Lesbarkeit für Menschen mit Leseschwäche

Vier Einstellungen helfen messbar, und keine davon kostet Gestaltung:

  1. Zeilenlänge zwischen 45 und 75 Zeichen.
  2. Zeilenhöhe ab 1,5 im Fließtext.
  3. Flattersatz statt Blocksatz. Blocksatz erzeugt unterschiedlich große Wortabstände, die als senkrechte Lücken durch den Absatz laufen. Auf Stufe AAA schließt 1.4.8 Blocksatz aus.
  4. Ausreichende Absatzabstände, damit der Block sich gliedert.

Für Spezialschriften wie OpenDyslexic ist ein Lesevorteil in Untersuchungen nicht belegt. Gut gemachte serifenlose Schriften mit unterscheidbaren Formen für großes I, kleines l und Ziffer 1 bringen mehr. Weitere Punkte stehen unter kognitive Barrierefreiheit.

Dünne Schnitte und der wahrgenommene Kontrast

Der Kontrastwert nach 1.4.3 wird aus zwei Farben berechnet und kennt die Strichstärke nicht. Eine Schrift mit font-weight: 200 in hellem Grau erreicht denselben gemessenen Wert wie derselbe Text in 400, liest sich aber deutlich schlechter. Für Fließtext bleibt 400 die Untergrenze, für Text auf farbigem Grund eher 500. Messen kannst du die Werte mit dem Kontrast-Check.

Icon-Schriften und Text als Bild

Icon-Fonts legen ihre Zeichen im privaten Bereich der Unicode-Tabelle ab. Fällt die Schrift aus, erscheint ein leeres Rechteck, und Screenreader lesen im schlechtesten Fall einen sinnlosen Buchstaben vor. Der Ersatz steht unter Icons und SVGs.

Text, der als Bild ausgeliefert wird, verliert jede Anpassbarkeit. Er skaliert unscharf, verträgt keine Textabstände und ist nicht durchsuchbar. 1.4.5 Bilder von Text lässt ihn nur für Logos und für Fälle zu, in denen die Darstellung selbst die Aussage ist. Mit variablen Schriften und clamp() gibt es kaum noch einen Anlass dafür.

Häufige Fragen

Wie ändere ich die Schriftart in CSS?

Über die Eigenschaft font-family, meist am body, weil sie sich an alle Nachfahren vererbt. Hinter der Wunschschrift stehen Ersatzschriften und am Ende eine generische Familie wie sans-serif. Formularelemente brauchen zusätzlich font: inherit, weil Browser ihnen eine eigene Schrift zuweisen.

px oder rem für die Schriftgröße?

rem für Schriftgrößen, weil der Wert sich auf die Grundschriftgröße des Browsers bezieht. Wer sie in den Browsereinstellungen hochsetzt, sieht die ganze Seite größer. Eine Angabe in Pixeln ignoriert diese Einstellung. Für Haarlinien und Rahmen bleibt px sinnvoll, dort ändert die Größe nichts an der Lesbarkeit.

Welcher Zeilenabstand ist der richtige?

Für Fließtext liegt der Bereich zwischen 1,5 und 1,7, notiert als Zahl ohne Einheit. WCAG 1.4.12 nennt 1,5 als Wert, der ohne Inhaltsverlust möglich sein muss. Überschriften kommen mit 1,1 bis 1,3 aus, weil große Schrift anteilig weniger Abstand benötigt. Eine Angabe mit Einheit vererbt sich falsch und ist deshalb zu vermeiden.

Wie viele Zeichen sollte eine Zeile haben?

Zwischen 45 und 75 Zeichen einschließlich Leerzeichen. Mit max-width: 65ch setzt du das direkt um, weil ch sich an der Zeichenbreite der aktuellen Schrift orientiert. Längere Zeilen erschweren den Sprung zum nächsten Zeilenanfang, kürzere zerreißen den Satzfluss.

Wie binde ich eine eigene Schrift ein?

Mit einer @font-face-Regel, die auf eine woff2-Datei auf dem eigenen Server zeigt, dazu font-display: swap gegen unsichtbaren Text während des Ladens. Der vollständige Weg einschließlich preload und der Einordnung zu Google Fonts steht unter CSS einbinden.

Verwandte Themen

Quellen

Gratis E-Book PDF, 37 Seiten HTML & Barrierefreiheit, WCAG & BFSG, GEO & SEO

Kostenloses E-Book

Das Praxishandbuch für sauberes, zugängliches Web

Alles rund um semantisches HTML, Barrierefreiheit, WCAG & BFSG, GEO und SEO — praxisnah und am echten Code. In mehreren Feedbackschleifen von Leserinnen und Lesern verbessert.

  • 3.000+ Downloads
  • 7. Auflage
  • 37 Seiten
  • PDF

Kein Spam. Abmeldung jederzeit mit einem Klick möglich.