Als Front-End-Entwickler, der für Kunden auf der ganzen Welt arbeitet, hatte ich immer Schwierigkeiten mit mehrsprachigen Websites – insbesondere mit Fällen, in denen sowohl Rechts-nach-links (RTL) als auch Links-nach-rechts (LTR) verwendet werden. Das gesagt, habe ich auf dem Weg ein paar Dinge gelernt und werde in diesem Beitrag ein paar Tipps teilen.
Lassen Sie uns auf Arabisch und Englisch arbeiten, nicht nur, weil Arabisch meine Muttersprache ist, sondern weil es ein klassisches Beispiel für RTL in Aktion ist.
Hinzufügen von RTL-Unterstützung zu einer Website
Bevor wir das tun, möchten wir Unterstützung für eine RTL-Sprache auf unserer Website hinzufügen. Es gibt zwei Möglichkeiten, dies zu tun, die beide nicht gerade ideal sind.
Nicht ideal: Verwendung einer spezifischen Schriftart für jede Richtung
Der erste Weg, wie wir das tun könnten, ist, sich auf das `dir`-Attribut (`direction`) eines beliebigen Elements zu verlassen (was normalerweise das `
`-Element ist, so dass die Richtung global gesetzt wird)./* For LTR, use Roboto */
[dir=ltr] body {
font-family: "Roboto", sans-serif;
}
/* For RTL, use Amiri */
[dir=rtl] body {
font-family: "Amiri", sans-serif;
}
PostCSS-RTL erleichtert die Generierung von Stilen für jede Richtung noch weiter, aber das Problem bei dieser Methode ist, dass Sie nur eine Schriftart verwenden, was nicht ideal ist, wenn Sie mehrere Sprachen in einem Absatz haben.
Hier ist der Grund. Sie werden feststellen, dass mehrsprachige Absätze die Benutzeroberfläche durcheinander bringen, da den arabischen Glyphen eine Standardschriftart zugewiesen wird, die nicht mit dem Element übereinstimmt.
Dies kann in einigen Browsern schlimmer sein als in anderen.
Ebenfalls nicht ideal: Verwendung einer einzigen Schriftart, die beide Sprachen unterstützt
Die zweite Option könnte die Verwendung von Schriftarten sein, die Unterstützung für beide Richtungen bieten. In meiner persönlichen Erfahrung schränkt die Verwendung nur einer Schriftart für beide Sprachen jedoch die Kreativität und Freiheit ein, für jede Richtung eine andere Schriftart zu verwenden. Es mag nicht so schlimm sein, je nach Designanforderungen. Aber ich habe definitiv an Projekten gearbeitet, bei denen es einen Unterschied macht.
Okay, was dann?
Wir brauchen eine einfachere Lösung. Laut MDN
Die Schriftauswahl endet nicht einfach mit der ersten Schriftart in der Liste, die auf dem System des Benutzers vorhanden ist. Vielmehr erfolgt die Schriftauswahl Zeichen für Zeichen, sodass, wenn eine verfügbare Schriftart keine Glyphe für ein benötigtes Zeichen hat, die nachfolgenden Schriftarten ausprobiert werden.
Das bedeutet, wir können immer noch die `font-family`-Eigenschaft verwenden, aber mit einem Fallback für Fälle, in denen die erste Schriftart keine Glyphe für ein Zeichen hat. Das löst tatsächlich beide oben genannten Probleme, zwei Fliegen mit einer Klappe!
body {
font-family: 'Roboto', 'Amiri', 'Galada', sans-serif;
}
Warum funktioniert das?
So wie Flexbox und CSS Grid CSS-Layouts viel flexibler machen, erleichtert der Zeichensatzalgorithmus die Arbeit mit Inhalten in verschiedenen Sprachen. Hier sagt W3C über das Abgleichen von Zeichen mit Schriftarten:
Wenn Text Zeichen wie kombinierende Markierungen enthält, sollte idealerweise das Basiszeichen mit derselben Schriftart wie die Markierung gerendert werden, dies gewährleistet eine ordnungsgemäße Platzierung der Markierung. Aus diesem Grund ist der Zeichensatzalgorithmus für Cluster spezialisierter als der allgemeine Fall des Abgleichs eines einzelnen Zeichens für sich. **Für Sequenzen, die Variationsselektoren enthalten, die die genaue Glyphe angeben, die für ein gegebenes Zeichen verwendet werden soll, versuchen Benutzeragenten immer einen System-Fallback für Schriftarten, um die entsprechende Glyphe zu finden, bevor die Standardschriftart des Basiszeichens verwendet wird.**
(Hervorhebung von mir)
Und wie werden Schriftarten abgeglichen? Die Spezifikation beschreibt die Schritte, die der Algorithmus durchführt, die ich hier paraphrasieren werde.
- Der Browser betrachtet einen Textcluster und versucht, ihn mit der Liste der in CSS deklarierten Schriftarten abzugleichen.
- Wenn er eine Schriftart findet, die alle Zeichen unterstützt, großartig! Das wird verwendet.
- Wenn der Browser keine Schriftart findet, die *alle* Zeichen unterstützt, liest er die Liste der Schriftarten erneut durch, um eine zu finden, die die nicht übereinstimmenden Zeichen unterstützt, und wendet sie auf diese spezifischen Zeichen an.
- Wenn der Browser keine Schriftart in der Liste findet, die weder *alle* Zeichen im Cluster noch einzelne Zeichen abgleicht, greift er auf die Standardsystemschriftart zurück und prüft, ob diese alle Zeichen unterstützt.
- Wenn die Systemschriftart übereinstimmt, wieder großartig! Das wird verwendet.
- Wenn die Systemschriftart nicht funktioniert, rendert der Browser eine fehlerhafte Glyphe.
Sprechen wir über Leistung
Die gerade betrachtete Sequenz kann die Leistung einer Website stark beeinträchtigen. Stellen Sie sich vor, der Browser müsste jede definierte Fallback-Option durchgehen, bestimmte Zeichen mit Glyphen abgleichen und Schriftdateien herunterladen, basierend auf dem, was er findet. Das kann sich zu viel Arbeit summieren, ganz zu schweigen von FOUT und anderen Rendering-Merkwürdigkeiten.
Das Ziel ist es, den Schriftart-Abgleich-Algorithmus entscheiden zu lassen, welche Schriftart auf jeden Text angewendet wird, anstatt sich auf eine Schriftart für beide Sprachen zu verlassen oder zusätzlichen CSS-Code hinzuzufügen, um verschiedene Richtungen zu handhaben. Wenn eine Schriftart nie angewendet wird (sagen wir, eine bestimmte Seite ist in RTL und hat keine LTR-Texte darauf oder umgekehrt), wird die weiter unten im Stapel befindliche Schriftart, die nicht verwendet wird, nie heruntergeladen.
Damit das funktioniert, müssen gute mehrsprachige Schriftarten ausgewählt werden. Gute mehrsprachige Schriftarten sind solche, die Glyphen für so viele Zeichen wie möglich enthalten, die Sie auf einer Seite voraussichtlich verwenden werden. Und wenn Sie keine finden können, die alle unterstützt, ist die Verwendung einer, die die meisten unterstützt und dann auf eine andere Schriftart zurückfällt, die es tut, ein effizienter Weg. Wenn das zufällig die Standardsystemschriftart ist, ist das genauso großartig, da es eine heruntergeladene Schriftdatei weniger ist.
Das Gute daran, die `font-family`-Eigenschaft die Schriftart für jede Glyphe entscheiden zu lassen (anstatt zusätzliche CSS-Selektoren für jede Richtung zu erstellen), ist, dass das Verhalten bereits vorhanden ist, wie wir zuvor dargelegt haben – wir müssen es einfach nutzen.
Toller Artikel, Kumpel,
Als englischer und arabischer Sprecher muss ich mich manchmal damit auseinandersetzen, beide Sprachen in derselben Zeile zu mischen, was in den meisten Chat- und Messenger-Apps fehlschlägt.
Dieses Konzept wird dieses Problem lösen.
Ich werde versuchen, dies in React Native zu testen und zu sehen, wie ich es implementieren kann.
Ich habe keine anderen Browser überprüft, aber in Chrome Version 80 (unter Windows) scheint es, dass in Ihrem ersten RTL-Beispiel (wo die englischen Glyphen auf `sans-serif` zurückfallen sollen) der englische Text tatsächlich mit einer Serifenschriftart gerendert wird!
Das stimmt, Tom. Ich habe es nachgeschlagen und festgestellt, dass es daran liegt, dass ich Amiri von Google Fonts verwendet habe, das standardmäßig lateinische Glyphen unterstützt. Wenn Sie also Google Fonts verwenden, müssen Sie die lateinische Schriftart als erste Option angeben, um diese Art von Konflikten zu vermeiden.
Guter Artikel, klar, prägnant und leicht verständlich. Danke.
Das mag wie ein alberner Kommentar klingen, aber wenn man Sprachen innerhalb eines bestimmten Blocks mischt, sollte man dann nicht die Snippets in einer anderen Sprache mit der entsprechenden Sprache für die semantische Auszeichnung kennzeichnen? (also im Fall Ihres Absatzes auf Arabisch, mit "exercitation" als exercitation)
Meinen Sie die Anführungszeichen?
Wenn das der Fall ist, stimme ich Ihnen zu und denke, dass es einen manuellen Ansatz erfordert.
Beim Titel dachte ich, dieser Artikel würde Überlegungen zu Schriftarten mit Sonderzeichen wie lateinischen Zeichen enthalten. Viele Schriftarten bei Google Fonts enthalten diese ÑÇÃÁÀÉÍÓÕÚ-Zeichen nicht und es ist ziemlich üblich, dass Websites diese Schriftarten verwenden. Eingabefelder und dynamischer Text, die sie verwenden, zeigen seltsame Zeichen an, wenn jemand ein akzentuiertes Zeichen eingibt.
Dies wird seit 2008 von Browsern unterstützt. Mein Freund erzählte mir davon, als wir einen technischen Blog in nicht-englischer Sprache betrieben, in dem Computerbegriffe in englischer Sprache innerhalb von burmesischen Absätzen vorkamen. Ich war mit den lateinischen Glyphen einer burmesischen Schriftart nicht zufrieden und da schlug mein Freund die Verwendung einer geordneten Schriftartliste vor.