Letter Spacing ist kaputt und es gibt nichts, was wir dagegen tun können… vielleicht

Avatar of Juan Diego Rodríguez
Juan Diego Rodríguez am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Dieser Beitrag entstand nach einem Gespräch, das ich mit Emilio Cobos führte – einem Senior-Entwickler bei Mozilla und Mitglied der CSSWG – über das letzte CSSWG-Gruppentreffen. Ich wollte wissen, was seiner Meinung nach die aufregendsten und interessantesten Themen waren, die bei ihrem letzten Treffen besprochen wurden. Da das Jahr 2024 vollgepackt ist mit so vielen neuen oder kommenden auffälligen Dingen wie Masonry-Layout, if()-Bedingungen, Anchor Positioning, View Transitions und was sonst noch alles, dachte ich, seine Antworten müssten darunter sein.

Er gab zu, dass meine Liste der Highlights die Mainstream-Themen in der Community gut widerspiegelte, insbesondere aus der Sicht eines Autors. Zu meiner Überraschung bezog sich seine Lieblingsdiskussion jedoch auf etwas völlig anderes: eine Ungenauigkeit bei der Art und Weise, wie die letter-spacing-Eigenschaft browserübergreifend gerendert wird. Es ist ein Fehler, der im Web so tief verwurzelt ist, dass Browser die CSS-Spezifikation seit Jahren ignorieren, und der aufgrund fehlender besserer Optionen und Kompatibilitätsproblemen nicht einfach gelöst werden kann.

Emilios Antwort ergibt Sinn – er arbeitet an Gecko, und das Rendern von Schriften ist eine Kunst für sich. Trotzdem verstand ich nicht genau, wo das Problem liegt, warum er es so interessant findet und sogar, warum es überhaupt existiert, da letter-spacing eine Eigenschaft ist, die so alt wie CSS selbst ist. Erst als ich tiefer in das „Kaninchenbau“-Thema Letter Spacing eintauchte, verstand ich, wie erstaunlich komplex das Problem wird, und ich hoffe, ich kann Sie für diese (nicht ganz so) einfache Eigenschaft genauso begeistern wie mich.

Was ist Letter Spacing?

Die Frage scheint einfach: Letter Spacing ist der Abstand zwischen Buchstaben. Hurra! Das war einfach – für Menschen. Für einen Computer hat die Frage, wie der Raum zwischen den Buchstaben gerendert werden soll, viel mehr Nuancen. Ein Mensch schreibt einfach den nächsten Buchstaben, ohne groß darüber nachzudenken. Computer hingegen benötigen eine Strategie, wie dieser Raum gerendert werden soll: Sollen sie den gesamten Raum am Anfang des Buchstabens hinzufügen, am Ende, oder ihn halbieren und auf beiden Seiten des Buchstabens hinzufügen? Sollte es bei Links-nach-Rechts-Sprachen (LTR) wie Englisch anders funktionieren als bei Rechts-nach-Links-Sprachen (RTL) wie Hebräisch? Diese Fragen sind entscheidend, da die Wahl eines Standards bestimmt, wie die Textmessung und Zeilenumbrüche im gesamten Web funktionieren.

Welche der drei Strategien wird im Web verwendet? Das hängt davon ab, wen man fragt. Die Implementierung in den CSS-Spezifikationen unterscheidet sich komplett von dem, was die Browser tun, und es gibt sogar Inkompatibilitäten zwischen den Rendering-Engines der Browser wie Gecko (Firefox), Blink (Chrome, Brave, Opera usw.) und WebKit (Safari).

Was die CSS-Spezifikation sagt

Gehen wir einen Schritt zurück und schauen uns erst einmal an, wie die Spezifikation sagt, dass Letter Spacing funktionieren sollte. Zum Zeitpunkt der Erstellung dieses Textes gilt für letter-spacing:

Gibt zusätzlichen Abstand zwischen typografischen Zeicheneinheiten an. Werte können negativ sein, es können jedoch implementierungsabhängige Grenzen bestehen.

Die formale Spezifikation ist noch ausführlicher, aber dieser Teil reicht aus, um zu verstehen, wie sich letter-spacing laut CSS-Spec verhalten soll. Das Schlüsselwort ist zwischen, was bedeutet, dass der Buchstabenabstand nur den Raum zwischen den Zeichen beeinflussen sollte. Ich weiß, das klingt ziemlich offensichtlich.

Laut dem Beispiel in der Spezifikation sollte also das folgende HTML

<p>a<span>bb</span>c</p>

…mit diesem CSS

p {
  letter-spacing: 1em;
}

span {
  letter-spacing: 2em;
}

…einen gleichen Abstand zwischen den beiden Buchstaben „b“ ergeben.

Letter spacing on paper. The letter spacing is only applied between the letters "b"s

Wenn wir jedoch denselben Code in einem beliebigen Browser ausführen (z. B. Chrome, Firefox oder Safari), sehen wir, dass der Abstand nicht nur zwischen den „b“-Buchstaben liegt, sondern auch am Ende des vollständigen Wortes.

Letter spacing on browsers. The letter spacing is applied between the letters "b"s and on the right-hand side of the last letter "b"

Was Browser tun

Ich dachte, es sei normal, dass letter-spacing den Abstand am Ende eines Zeichens anfügt, und wusste nicht, dass die Spezifikation etwas anderes besagt. Aber wenn man darüber nachdenkt, wirkt das aktuelle Verhalten tatsächlich falsch… wir sind es nur einfach so gewohnt.

Warum halten sich Browser hier nicht an die Spezifikation?

Wie wir bereits gesehen haben, ist Letter Spacing für Computer nicht trivial, da sie sich an eine Strategie halten müssen, wo der Abstand angewendet wird. Im Fall der Browser war es der Standard, einen individuellen Abstand am Ende jedes Zeichens anzuwenden, ungeachtet dessen, ob dieser Raum über das Ende des Wortes hinausgeht. Es war vielleicht nicht die beste Wahl, aber darauf hat sich das Web eingespielt, und eine Änderung zum jetzigen Zeitpunkt würde zu allen möglichen Text- und Layoutverschiebungen im gesamten Web führen.

Dies hinterlässt bei Elementen mit größerem Buchstabenabstand eine Lücke am Ende, was für LTR-Text halbwegs akzeptabel ist, aber in einem RTL-Schreibmodus ein Loch am Anfang des Textes hinterlässt.

Das Problem wird bei zentriertem Text deutlicher, wo der abschließende Abstand den Text aus dem exakten Zentrum des Elements schiebt. Wahrscheinlich mussten Sie schon mindestens einmal ein padding auf der gegenüberliegenden Seite eines Elements hinzufügen, um den letter-spacing auszugleichen, den Sie auf den Text angewendet haben, beispielsweise bei einem Button.

Wie Sie sehen können, erzeugt die blaue Markierung eine symmetrische Pyramide, der unser Text leider nicht folgt.

Schlimmer noch: „Ende jedes Zeichens“ bedeutet für Browser etwas Unterschiedliches, insbesondere bei der Arbeit im RTL-Schreibmodus. Chrome und Safari (Blink/WebKit) sagen, das Ende eines Zeichens ist immer auf der rechten Seite. Firefox (Gecko) hingegen fügt den Raum am „Lese-Ende“ hinzu – was im Hebräischen und Arabischen die linke Seite ist. Sehen Sie den Unterschied selbst.

Side-by-side comparison of letter spacing on Gecko and Blink/Webkit

Kann das behoben werden?

Der erste Gedanke, der einem in den Sinn kommt, ist, einfach der Spezifikation zu folgen und den unnötigen Platz am letzten Zeichen wegzuschneiden. Aber diese (Anti-)Lösung bringt Kompatibilitätsrisiken mit sich, die schlichtweg zu groß sind, um sie auch nur in Erwägung zu ziehen: Textmessungen und Zeilenumbrüche würden sich ändern, was möglicherweise auf vielen Websites zu Fehlern führen würde. Seiten, die diesen zusätzlichen Platz mit Workarounds entfernt haben, taten dies wahrscheinlich durch Verschieben des padding/margin des Elements. Eine Änderung des aktuellen Verhaltens würde diese Offsets also hinfällig machen oder das Layout zerstören.

Es gibt zwei reale Optionen, wie letter-spacing korrigiert werden kann: Überarbeitung der Art und Weise, wie der Raum um das Zeichen verteilt wird, oder das Anbieten einer Option für Entwickler, mit der wir wählen können, wo wir den abschließenden Platz haben möchten.

Option 1: Überarbeitung der Platzverteilung

Die erste Option wäre, die aktuelle Definition von letter-spacing so zu ändern, dass sie in etwa so lautet:

Gibt den zusätzlichen Abstand an, der auf jede typografische Zeicheneinheit angewendet wird, außer auf solche mit einem Vorschub von Null. Der zusätzliche Abstand wird gleichmäßig zwischen der Inline-Start- und Inline-End-Seite der typografischen Zeicheneinheit aufgeteilt. Werte können negativ sein, es können jedoch implementierungsabhängige Grenzen bestehen.

Einfach gesagt: Anstatt dass Browser den zusätzlichen Platz am Ende des Zeichens hinzufügen, würden sie ihn gleichmäßig auf Anfang und Ende verteilen, was zu symmetrischem Text führt. Auch dies würde Textmessungen und Zeilenumbrüche verändern, wenn auch in geringerem Maße.

Letter spacing with the symmetrical fix. The letter spacing is equally applied around the letters "b"s

Nun ist mittig ausgerichteter Text auch wirklich korrekt in der Mitte ausgerichtet.

Different examples of letter spacing being distributed between letters and achieving a symmetrical look

Option 2: Entwicklern eine Auswahlmöglichkeit geben

Selbst wenn der Versatz halbiert wird, könnte dies immer noch zu Layoutverschiebungen führen, was für einige (zu Recht) inakzeptabel ist. Es ist ein Dilemma: Die meisten Seiten benötigen es oder würden zumindest davon profitieren, letter-spacing so zu lassen, wie es ist, während neue Seiten symmetrisches Letter Spacing bevorzugen würden. Glücklicherweise könnten wir beides tun, indem wir Entwicklern die Wahl lassen, wie der Raum auf Zeichen angewendet wird. Die Syntax steht noch in den Sternen, aber wir könnten eine neue Eigenschaft erhalten, um zu wählen, wo der Abstand platziert werden soll:

letter-spacing-justify: [ before | after | left | right | between | around];

Jeder Wert gibt an, wo der Abstand hinzugefügt werden soll, unter Berücksichtigung der Textrichtung:

  • before: Der Abstand wird am Anfang des Buchstabens hinzugefügt, entsprechend der Richtung der Sprache.
  • after: Der Abstand wird am Ende des Buchstabens hinzugefügt, entsprechend der Richtung der Sprache.
  • left: Der Abstand wird links vom Buchstaben hinzugefügt, ungeachtet der Richtung der Sprache.
  • right: Der Abstand wird rechts vom Buchstaben hinzugefügt, ungeachtet der Richtung der Sprache.
  • between: Der Abstand wird zwischen den Zeichen hinzugefügt, entsprechend der Spezifikation.
  • around: Der Abstand wird um den Buchstaben herum verteilt.

Logischerweise wäre das aktuelle Verhalten der Standard, um nichts kaputt zu machen, und letter-spacing würde zu einer Kurzschreibweise (Shorthand) für beide Eigenschaften (Länge und Platzierung) werden.

letter-spacing: 1px before;
letter-spacing: 1px right;
letter-spacing: 1px around;

letter-spacing: 1px;
/* same as: */
letter-spacing: 1px before;

Was ist mit einer dritten Option?

Und natürlich besteht die dritte Option darin, alles so zu lassen, wie es ist. Ich würde sagen, das ist unwahrscheinlich, da die CSSWG beschlossen hat, in dieser Angelegenheit tätig zu werden, und sie werden sich wahrscheinlich für die zweite Option entscheiden, wenn ich darauf wetten müsste.

Jetzt wissen Sie, dass letter-spacing kaputt ist… und wir damit leben müssen, zumindest vorerst. Aber es gibt Optionen, die helfen könnten, das Problem in Zukunft zu korrigieren.