Features von übermorgen: Font Loading API

Tales from the Web side  –  7 Kommentare

Die Font Loading API bietet einen standardisierten Weg, um Schriften dynamisch per JavaScript zu laden. Dadurch macht sie die bisherigen Vorgehen überflüssig.

Wurden in der Anfangszeit des Internet bei der Gestaltung von Webseiten noch einige wenige Schriftarten wie Arial, Times New Roman oder Helvetica verwendet, weil man hierbei davon ausgehen konnte, dass diese auf den Rechnern aller Nutzer vorinstalliert waren, hat sich das seitdem (zum Glück) geändert: Dank der CSS-Regel @font-face lassen sich beliebige Schriftarten als Ressource angeben, die dann der Browser (beispielsweise von Anbietern wie Google Fonts oder Adobe TypeKit) bei Bedarf herunterlädt.

Mitunter sind die entsprechenden Schriftdateien jedoch im Vergleich zu den restlichen Daten der jeweiligen Webseite relativ groß – sprich bis die Schriftdateien vollständig heruntergeladen sind, kann es (insbesondere bei langsamen Verbindungen) zu einer Verzögerung in der Darstellung kommen. Konkret heißt das, dass entsprechende Texte auf der Webseite erst in einer Standardschriftart dargestellt und später – sobald die gewünschte Schriftart geladen wurde – in dieser dargestellt werden.

Hinsichtlich der Usability ist es daher ratsam, gegebenenfalls entweder ganz auf alternative (Standard-)Schriftarten auszuweichen oder solange mit der Darstellung der Texte auf der Webseite zu warten, bis die gewünschte Schriftart geladen wurde.

Die Font Loading API

Hier schaffen JavaScript-Bibliotheken wie TypeKits Web Font Loader oder Font Face Observer Abhilfe: Zum einen ist es hierüber möglich, Schriftarten dynamisch per JavaScript zu laden, zum anderen wird man über entsprechende Events darüber informiert, wann und ob eine Schriftart erfolgreich geladen wurde.

Und genau hier setzt die Font Loading API (bzw. genauer: die CSS Font Loading Module Level 3 Spezifikation) des W3C an, die sich momentan im Status "Editor's Draft“ befindet und folgende Interfaces definiert:

  • FontFace: repräsentiert eine Schriftart.
  • FontFaceSet: repräsentiert eine Menge von Schriftarten. Wird durch das in der Eigenschaft document.fonts hinterlegte Objekt implementiert und enthält Objekte vom Typ FontFace.
  • FontFaceSource: repräsentiert eine Quelle für das Laden von Schriftarten. Wird durch die Interfaces Document und WorkerGlobalScope implementiert. Über die Eigenschaft fonts gelangt man an ein FontFaceSet, das alle Schriften des jeweiligen Dokuments enthält.
  • FontFaceSetLoadEvent: repräsentiert Events, die im Zusammenhang mit dem Laden von Schriftarten ausgelöst werden.

Schriften dynamisch laden

Das Laden einer Schriftart erfolgt in zwei Schritten: im ersten sind die entsprechenden Schriftdaten herunterzuladen, im zweiten Schritt muss die Schriftart – bevor sie innerhalb der Webseite im CSS genutzt werden kann – dem FontFaceSet der jeweiligen Webseite hinzugefügt werden.

Zuerst benötigt man dazu eine Objektinstanz von FontFace: Dem entsprechenden Konstruktor übergibt man den Namen der Schriftart sowie die Ressource, von der die Schriftart geladen werden soll (die vollständige URL wurde in den folgenden Code-Beispielen aus Platzgründen gekürzt). Optional lässt sich als dritter Parameter ein Konfigurationsobjekt übergeben, über das sich Schriftstil, Schriftstärke, Schriftvarianten etc. definieren lassen.

let fontFace = new FontFace('OpenSans','url(https://fonts.gstatic.com
/s/opensans/v13/......woff2)');

Der Aufruf der Methode load() startet dann das asynchrone Laden der so konfigurierten Schriftart. Entsprechend liefert die Methode ein Promise-Objekt zurück, über welches sich wie gewohnt per Aufruf von then() und catch() Callback-Funktionen angeben lassen, um über das Laden der Schriftart bzw. eventuell auftretende Fehler informiert zu werden.

'use strict';
const log = console.log;
let fontFace = new FontFace('OpenSans','url(https://fonts.gstatic.com
/s/opensans/v13/......woff2)');
fontFace.load()
.then(loadedFontFace => {
log('Schriftart geladen');
log(loadedFontFace.family); // Schriftfamilie
log(loadedFontFace.style); // Schriftstil
log(loadedFontFace.weight); // Schriftstärke
log(loadedFontFace.stretch); // Schriftweite
log(loadedFontFace.unicodeRange); // Unicode-Bereich
log(loadedFontFace.variant); // Schriftvariante
log(loadedFontFace.featureSettings); // Schriftfeatures
log(loadedFontFace.status); // Status
})
.catch(error => console.error('Fehler beim Laden der Schriftart'));

Alternativ lassen sich diese Callback-Funktionen auch an dem der Eigenschaft loaded hinterlegten Promise-Objekt definieren:

fontFace.loaded
.then((loadedFontFace) =>
console.log('Schriftart "${loadedFontFace.family}" geladen.'))
.catch(error => console.error(error));
fontFace.load();

Schriften verfügbar machen

Bei dem Objekt document.fonts vom Typen FontFaceSet handelt es sich um ein Set-ähnliches Objekt, sprich es leitet zwar nicht direkt von Set ab, verfügt aber trotzdem über dessen Methoden (wie entries(), keys(), values(), clear(), add() etc.).

Heruntergeladene Schriftarten können dem FontFaceSet daher per add() hinzugefügt werden. Anschließend lässt sich die Schriftart bedenkenlos verwenden.

'use strict';
const fontFaceSet = document.fonts;
let fontFace = new FontFace('OpenSans','url(https://fonts.gstatic.com
/s/opensans/v13/......woff2)');
fontFace.load()
.then(loadedFontFace => {
console.log('Schriftart geladen');
fontFaceSet.add(loadedFontFace);
console.log('Schriftart hinzugefügt');
// Ab hier kann die Schriftart sicher genutzt werden.
})
.catch(error => console.error('Fehler beim Laden der Schriftart'));

Darüber hinaus bietet FontFaceSet zwei weitere Methoden an: Die Methode load() kombiniert quasi die beiden Schritte des Herunterladens und Hinzufügens einer oder mehrerer Schriftarten, über die Methode check() lässt sich zudem überprüfen, ob die angegebenen Schriftarten bereits vollständig geladen wurden und ohne Darstellungsprobleme innerhalb der Webseite verwendet werden können.

Der Status des Ladens lässt sich zudem über die Eigenschaft ready einsehen: dabei handelt es sich erneut um ein Promise-Objekt, dessen then()-Callback ausgeführt wird, sobald alle Schriftarten im FontFaceSet zur Verfügung stehen:

fontFaceSet.ready
.then((loadedFontFaceSet) => {
log(`Insgesamt sind ${loadedFontFaceSet.size} FontFaces geladen.');
for (let fontFace of document.fonts.values()) {
log(fontFace.family);
}
})
})

Übrigens: Für alle Schriftarten, die per CSS über die Regel @font-face definiert wurden, werden automatisch entsprechende FontFace-Objektinstanzen erzeugt und dem FontFaceSet in documents.fonts hinzugefügt. Außerdem praktisch: Änderungen im CSS haben Auswirkungen auf diese FontFace-Objektinstanzen, Änderungen an den Objektinstanzen Auswirkungen auf das CSS.

Fazit

Die Font Loading API bietet einen standardisierten Weg, um Schriften dynamisch per JavaScript zu laden. Laut caniuse.com wird die API aktuell unter anderem von Firefox, Chrome, Safari und Opera implementiert. Der Internet Explorer und auch Edge bieten dagegen momentan noch keinen Support an.