mitmario.dev

Eigene Schriften einbinden

CSS Im Browser 5 Min Lesezeit 4 BeispieleLektion 3 von 7

Manchmal hat eine Marke eine eigene Schrift, und dann reicht der System-Font-Stack nicht. Du lädst sie nach, und ab da geht es weniger um Gestaltung als um Ladezeiten und Datenschutz.

Zu dieser Lektion gibt es keine Aufgabe. Eine Schriftdatei gibt es hier nicht, also gäbe es auch nichts zu prüfen. Im Reiter „Netzwerk“ kannst du das sogar sehen. Beim Beispiel „Eine font-face-Deklaration“ steht dort unter index.html und styles.css eine dritte Zeile, /schriften/meine-schrift.woff2. Sie hat keine Größe, und wo bei einem Bild „geladen“ stünde, steht ein Strich. Der Browser hat die Datei angefragt, weil eine Regel die Schrift benutzt, und unter diesem Pfad liegt nichts. So still sieht ein falscher Pfad in src auch auf einer echten Seite aus. Die Seite fällt auf die Fallback-Schrift zurück, und gemeldet wird nichts. In den übrigen Beispielen stehen der Code und das, was du im echten Browser daran sehen würdest.

Gewichte und Schnitte

Eine Schrift ist selten eine einzige Datei, sondern eine Familie aus Schnitten, also aus Fassungen in einem bestimmten Gewicht oder Stil, etwa normal, fett oder kursiv. Daran hängt, was font-weight bewirkt.

font-weight nimmt Zahlen von 1 bis 1000. Gebräuchlich sind die Hunderter von 100 bis 900. normal ist 400, bold ist 700.

Die Gewichte von 100 bis 900
p {
  font-family: system-ui, sans-serif;
  font-size: 20px;
  margin: 0 0 4px 0;
}

.w300 {
  font-weight: 300;
}

.w400 {
  font-weight: 400;
}

.w600 {
  font-weight: 600;
}

.w700 {
  font-weight: 700;
}

.w900 {
  font-weight: 900;
}

Wie viele Stufen du tatsächlich siehst, hängt an der Schrift. Bringt sie nur zwei Schnitte mit, sehen 300, 400 und 500 gleich aus, und 600 bis 900 ebenfalls.

Fehlt der fette Schnitt, rechnet der Browser einen aus und verdickt dafür die Striche. Das heißt Faux Bold. Das Ergebnis wirkt unruhig, weil die Buchstabenabstände nicht mehr stimmen. Du erkennst es daran, dass die fette Variante aussieht wie die normale mit einem Schatten dahinter.

Dasselbe gilt für font-style: italic. Fehlt der kursive Schnitt, kippt der Browser die aufrechte Schrift schräg, und das ist etwas anderes als eine echte Kursive, in der viele Buchstaben eine andere Form haben. Mit oblique verlangst du diese Schrägstellung ausdrücklich. Mit italic nimmt der Browser zuerst den echten Schnitt, wenn es ihn gibt.

Anmelden mit font-face

@font-face ist keine Regel, die etwas gestaltet. Sie meldet eine Schriftdatei unter einem Namen an, den du danach in font-family benutzen kannst.

Eine font-face-Deklaration
/* Die Deklaration meldet eine Schrift an. Sie sagt nicht,
   wo sie benutzt wird, das machen die Regeln darunter. */
@font-face {
  font-family: "Meine Schrift";
  src: url("/schriften/meine-schrift.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* Der angemeldete Name steht danach ganz normal in der
   Liste, und dahinter der Fallback für den Fall, dass
   die Datei nicht ankommt. */
body {
  font-family: "Meine Schrift", Georgia, serif;
  font-size: 18px;
  line-height: 1.5;
}

Im Beispiel stehen fünf Angaben. Pflicht sind nur die ersten beiden, also der Name, unter dem du die Schrift ansprechen willst, und die Adresse der Datei. Dazu kommen das Gewicht und der Stil, für die sie steht. Und font-display, dazu gibt es weiter unten einen eigenen Abschnitt.

Das Format ist heute immer woff2. Es ist am stärksten komprimiert und wird von jedem Browser verstanden, den es noch gibt. In älteren Anleitungen stehen vier oder fünf Formate untereinander. Das kannst du dir sparen.

Mit font-weight und font-style erfährt der Browser, für welchen Fall diese Datei da ist. Hast du einen normalen und einen fetten Schnitt, sind das zwei Deklarationen mit demselben font-family-Namen und verschiedenen Gewichten. Der Browser sucht sich dann die passende heraus.

Ein Bereich beim Gewicht
/* So sieht die Anmeldung einer variablen Schrift aus:
   ein Bereich statt einer Zahl beim Gewicht.

   @font-face {
     font-family: "Meine Schrift";
     src: url("/schriften/variabel.woff2") format("woff2");
     font-weight: 100 900;
     font-display: swap;
   }
*/

p {
  font-family: system-ui, sans-serif;
  font-size: 18px;
  margin: 0 0 8px 0;
}

.w300 {
  font-weight: 300;
}

.w400 {
  font-weight: 400;
}

.w600 {
  font-weight: 600;
}

.w800 {
  font-weight: 800;
}

Bei einer variablen Schrift steckt alles in einer einzigen Datei. Statt einer Zahl steht bei font-weight ein Bereich wie 100 900, und der Browser kann jedes Gewicht dazwischen erzeugen. Sie kann kleiner sein als zwei einzelne Schnitte und ist deutlich flexibler. Im Beispiel steht diese Anmeldung nur im Kommentar, weil es hier keine Datei gibt. Die Gewichte siehst du deshalb an den vier Absätzen in der Schrift des Systems.

font-display gegen den unsichtbaren Text

Bis die Schriftdatei da ist, muss der Browser entscheiden, was er anzeigt. Ohne Anweisung wartet er, und zwar bis zu drei Sekunden. So lange ist der Text unsichtbar.

Mit font-display: swap zeigt der Browser sofort den Fallback und tauscht die Schrift aus, sobald sie da ist. Der Text ist von der ersten Sekunde an lesbar, dafür springt das Layout beim Wechsel.

Die anderen drei Werte sind für Sonderfälle. block schreibt das Warten ausdrücklich fest, also genau das Verhalten, das die Browser heute ohnehin von sich aus wählen. fallback gibt der Schrift ein kurzes Zeitfenster und benutzt danach dauerhaft den Fallback. optional überlässt dem Browser die Entscheidung, und bei schlechter Verbindung lädt er die Schrift gar nicht erst.

Für fast alle Seiten nehme ich swap.

Selbst hosten statt einbetten

Schriften von einem fremden Dienst einzubinden ist bequem und hat zwei Haken.

Der erste ist die Geschwindigkeit. Eine zweite Domain bedeutet eine zweite Verbindung mit allem, was dazugehört. Früher konnte ein Besucher die Datei schon von einer anderen Seite im Zwischenspeicher haben. Diesen Vorteil gibt es seit Chrome 86 nicht mehr, denn der Speicher ist dort je Seite getrennt.

Der zweite ist der Datenschutz. Bei jedem Seitenaufruf geht die IP-Adresse deiner Besucher an den fremden Anbieter, ohne dass sie gefragt wurden. Das Landgericht München I hat einem Besucher deshalb am 20.01.2022 (Az. 3 O 17493/20) 100 Euro Schadenersatz zugesprochen, weil eine Seite ihre Schriften auf diese Weise von Google geladen hatte.

Beides ist gelöst, wenn du die Datei herunterlädst und neben deine eigenen Dateien legst. Das ist kaum mehr Arbeit als das Einbetten.

Für die eine Schrift, die im ersten Bildschirm steht, lohnt zusätzlich ein <link rel="preload" href="/schriften/meine-schrift.woff2" as="font" type="font/woff2" crossorigin> im head. Der Browser findet die Datei sonst erst, wenn er das Stylesheet gelesen und die Regeln angewandt hat, und das ist spät.

Der Fallback entscheidet, wie es aussieht

Zwei Fallbacks, zwei Umbrüche
/* Die Breite steht in Pixeln und nicht in ch: ch hängt
   an der Schrift, und dann wären die beiden Kästen
   verschieden breit und nichts mehr vergleichbar. */
p {
  font-size: 18px;
  width: 300px;
  border: 1px solid #d4d4d8;
  padding: 8px;
  margin-bottom: 12px;
}

/* Zwei Fallbacks im Vergleich. Wichtiger als das
   Aussehen ist, wo die Zeilen umbrechen. */
.eine {
  font-family: Georgia, serif;
}

.andere {
  font-family: "Arial Narrow", Arial, sans-serif;
}

Solange die Schrift lädt, sieht die Seite nach dem Fallback aus. Und wenn beide unterschiedlich breit laufen, springt beim Wechsel das ganze Layout.

Den Fallback sucht man deshalb auch nach der Breite aus und nicht nur nach dem Aussehen. Im Beispiel steht zweimal derselbe Satz in einem gleich breiten Kasten und in derselben Größe. Trotzdem brechen die Zeilen an anderen Stellen um. Diesen Sprung sieht ein Besucher, wenn die richtige Schrift ankommt.

Feinjustieren lässt sich das mit size-adjust, ascent-override und descent-override in einer eigenen @font-face-Deklaration für die Fallback-Schrift. Safari kennt davon bisher nur size-adjust (Stand Oktober 2026). Das ist Feinarbeit für den Fall, dass der Sprung wirklich stört. Für den Anfang reicht eine Fallback-Schrift mit ähnlicher Breite.

Zum Mitnehmen

@font-face meldet eine Schriftdatei unter einem Namen an, im Format woff2 und mit font-display: swap, damit der Text sofort lesbar ist. Selbst gehostet geht keine IP-Adresse an Dritte, und ein Fallback mit ähnlicher Breite hält den Sprung klein.

Jetzt du

Basis Konto, kostenlos

Im Editor änderst du die Beispiele dieser Lektion und lässt sie gleich laufen. So merkst du am schnellsten, ob es sitzt.

Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.

Was in dieser Lektion steckt

  • Artikel mit 4 Beispielen zum Ausprobieren

    Steht hier, ohne Konto lesbar.