RTL- und LTR-abhängiges Styling direkt in CSS, ganz ohne JavaScript-Richtungserkennung
Sobald ein Shop eine Store-View mit arabischer oder hebräischer Sprache anbietet, muss sich das Layout automatisch an die Schreibrichtung anpassen, von rechts nach links statt von links nach rechts. Die Pseudoklasse :dir() reagiert direkt auf die tatsächlich berechnete Textrichtung eines Elements, unicode-bidi steuert das Verhalten bei gemischtem Text, und logical properties übernehmen den Rest, ohne dass ein einziges JavaScript-Snippet die Richtung erkennen müsste.
Inhaltsverzeichnis
- 1. Warum mehrsprachige Shops mehr brauchen als ein dir-Attribut auf html
- 2. Die :dir()-Pseudoklasse: gezielt auf berechnete Richtung reagieren
- 3. unicode-bidi im Detail: Kontrolle über den bidirektionalen Textalgorithmus
- 4. Zusammenspiel mit logical properties: margin, padding und Ausrichtung
- 5. Icons und Pfeile spiegeln: wann :dir() unverzichtbar bleibt
- 6. Formulare und Eingabefelder in gemischt-sprachigen Layouts
- 7. RTL-Layout testen, ohne die Browsersprache umzustellen
- 8. Barrierefreiheit: warum korrekte Bidi-Behandlung auch ein WCAG-Thema ist
- 9. Praxis-Einsatz im Shop: mehrsprachige Store-Views mit Arabisch oder Hebräisch
- 10. Zusammenfassung
- 11. FAQ
1. Warum mehrsprachige Shops mehr brauchen als ein dir-Attribut auf html
Der naheliegendste Schritt für ein RTL-taugliches Layout ist das dir-Attribut auf dem html-Element, das die grundlegende Textrichtung der gesamten Seite festlegt. Das reicht jedoch nicht in jedem Fall aus, denn einzelne Elemente können eine abweichende Richtung besitzen, etwa ein eingebettetes Produktcode-Feld, das auch in einer arabischen Store-View immer von links nach rechts gelesen werden soll, oder ein nutzergenerierter Kommentar, dessen Sprache und damit Richtung sich vom Rest der Seite unterscheidet.
Genau für diese Fälle reicht ein einzelnes, globales dir-Attribut nicht aus. CSS braucht eine Möglichkeit, gezielt auf die tatsächlich wirksame Textrichtung eines einzelnen Elements zu reagieren, unabhängig davon, ob diese Richtung vom übergeordneten html-Element geerbt, per dir-Attribut auf dem Element selbst gesetzt oder vom Browser automatisch aus dem Textinhalt erkannt wurde. Genau das leistet die Pseudoklasse :dir().
2. Die :dir()-Pseudoklasse: gezielt auf berechnete Richtung reagieren
:dir(rtl) und :dir(ltr) greifen auf die tatsächlich berechnete Textrichtung eines Elements zu, nicht nur auf ein explizit gesetztes dir-Attribut. Das ist der entscheidende Unterschied zum einfacheren Attribut-Selektor [dir="rtl"]: Ein Element mit dir="auto", dessen Richtung der Browser aus dem enthaltenen Text ableitet, matcht :dir() korrekt entsprechend der erkannten Richtung, während [dir="rtl"] in diesem Fall gar nicht greifen würde, weil im Markup wörtlich nur auto steht.
Praktisch bedeutet das: Ein Icon, das in LTR-Kontext links vom Text steht und in RTL-Kontext rechts stehen soll, lässt sich mit zwei :dir()-Regeln zuverlässig steuern, ganz ohne dass JavaScript die tatsächliche Richtung zur Laufzeit ermitteln und als Klasse auf das Element schreiben müsste. Die Pseudoklasse funktioniert außerdem auf jedem beliebigen Element, nicht nur auf html oder body, was sie auch für einzelne, gemischt-sprachige Komponenten innerhalb einer Seite nutzbar macht.
/* Icon-Ausrichtung abhaengig von der berechneten Textrichtung */
.search-input-wrapper .icon {
position: absolute;
inset-inline-start: 0.75rem;
}
/* :dir() reagiert auch auf dir="auto", nicht nur auf explizites dir="rtl" */
.product-badge:dir(rtl) {
transform: scaleX(-1);
}
3. unicode-bidi im Detail: Kontrolle über den bidirektionalen Textalgorithmus
Der Browser ordnet gemischten Text, etwa einen arabischen Satz mit einer eingebetteten lateinischen Produktnummer, standardmäßig über den Unicode Bidirectional Algorithm an, der die Richtung jedes Zeichens anhand seiner Unicode-Eigenschaften bestimmt. In den meisten Fällen liefert dieser Algorithmus ein korrektes Ergebnis, doch bei technischen Inhalten wie Artikelnummern, IBAN-Nummern oder URL-Fragmenten innerhalb eines RTL-Satzes kann die automatische Anordnung zu einer für Muttersprachler verwirrenden Lesereihenfolge führen.
unicode-bidi steuert, wie stark ein Element in diesen Algorithmus eingreift. Der Wert isolate kapselt den Inhalt eines Elements gegenüber seiner Umgebung, sodass eine eingebettete Zahl oder ein eingebetteter lateinischer Begriff nicht von der umgebenden RTL-Richtung beeinflusst wird und umgekehrt. plaintext geht weiter und lässt den Browser die Richtung des Elements komplett neu aus dessen eigenem Inhalt bestimmen, unabhängig von der Richtung des Elternelements, was sich besonders für nutzergenerierte Inhalte mit unbekannter Sprache eignet.
/* Artikelnummer bleibt lesbar, auch eingebettet in einen RTL-Satz */
.sku-inline {
unicode-bidi: isolate;
direction: ltr;
}
/* Nutzergenerierter Kommentar: Richtung komplett aus dem Inhalt ableiten */
.user-comment {
unicode-bidi: plaintext;
}
4. Zusammenspiel mit logical properties: margin, padding und Ausrichtung
Klassische physische Eigenschaften wie margin-left oder text-align: left beschreiben eine feste Bildschirmseite und ignorieren die Textrichtung völlig, weshalb ein für LTR gebautes Layout in einer RTL-Store-View ohne weitere Anpassung schlicht falsch aussieht: Abstände sitzen auf der falschen Seite, Text richtet sich zur falschen Kante aus. Logical properties wie margin-inline-start, padding-inline-end oder text-align: start lösen dieses Problem strukturell, indem sie sich immer relativ zur aktuellen Schreibrichtung ausrichten, statt eine feste Bildschirmseite zu meinen.
In der Praxis bedeutet das: Ein einmal mit logical properties gebautes Layout passt sich automatisch an, sobald sich die Textrichtung ändert, egal ob diese Änderung über das dir-Attribut, eine :dir()-Regel oder unicode-bidi: plaintext zustande kommt. :dir() bleibt trotzdem notwendig für alles, was logical properties nicht abdecken, etwa das Spiegeln eines Icons oder eine komplett unterschiedliche Transform-Regel je nach Richtung.
/* Funktioniert automatisch in LTR und RTL, ohne :dir()-Regel */
.card {
padding-inline: 1.5rem;
margin-inline-start: 1rem;
text-align: start;
border-inline-start: 3px solid var(--accent);
}
5. Icons und Pfeile spiegeln: wann :dir() unverzichtbar bleibt
Logical properties lösen Abstände, Ausrichtung und Rahmen, aber nicht jedes visuelle Element passt sich automatisch an eine Richtungsänderung an. Ein Pfeil-Icon, das in LTR nach rechts zeigt, um weiter oder nächste Seite zu bedeuten, muss in RTL nach links zeigen, um dieselbe Bedeutung zu transportieren, weil sich in RTL auch die gedachte Leserichtung und damit die intuitive Bedeutung von vorwärts umkehrt. Ein SVG-Icon selbst kennt seine Bedeutung nicht, weshalb diese Spiegelung explizit in CSS passieren muss.
:dir(rtl) mit einer transform: scaleX(-1)-Regel ist dafür der zuverlässigste Ansatz, weil er direkt an die tatsächlich wirksame Richtung gekoppelt ist und automatisch greift, unabhängig davon, ob die Richtung vom html-Element geerbt oder lokal überschrieben wurde. Wichtig ist dabei, nur Icons mit tatsächlicher Richtungsbedeutung zu spiegeln, etwa Pfeile oder Chevrons, nicht aber Icons wie ein Warenkorb-Symbol oder ein Uhr-Icon, deren Bedeutung richtungsunabhängig ist.
/* Nur richtungsbehaftete Icons spiegeln, nicht neutrale Symbole */
.icon-arrow-next:dir(rtl),
.icon-chevron:dir(rtl) {
transform: scaleX(-1);
}
6. Formulare und Eingabefelder in gemischt-sprachigen Layouts
Eingabefelder für strukturierte Daten wie E-Mail-Adressen, Telefonnummern oder IBAN-Nummern sollten unabhängig von der Seitenrichtung immer direction: ltr behalten, weil diese Formate selbst festen internationalen Konventionen folgen und eine gespiegelte Anzeige die Eingabe eher erschwert als erleichtert. Gleichzeitig soll das Label neben dem Feld weiterhin der Seitenrichtung folgen, damit das gesamte Formular optisch konsistent mit dem Rest der RTL-Seite bleibt.
unicode-bidi: isolate in Kombination mit direction: ltr auf dem Eingabefeld selbst erreicht genau das: Das Feld bleibt intern LTR und von der Umgebung isoliert, während Label, Fehlermeldung und Layout drumherum ganz normal der geerbten oder per :dir() gesetzten Richtung folgen. Diese Kombination ist besonders wichtig bei Checkout-Formularen, bei denen eine falsch dargestellte IBAN oder Telefonnummer direkt zu Eingabefehlern und abgebrochenen Bestellungen führen kann.
7. RTL-Layout testen, ohne die Browsersprache umzustellen
Für einen schnellen visuellen Test reicht es, dir="rtl" testweise direkt im DevTools-Elementinspektor auf das html-Element zu setzen, ohne die Systemsprache oder die Store-View tatsächlich zu wechseln. So lassen sich Layout-Brüche wie falsch positionierte Icons, physische statt logische Abstände oder unerwünscht gespiegelte, richtungsneutrale Symbole schnell identifizieren, bevor eine echte arabische oder hebräische Store-View produktiv geschaltet wird.
Ein häufiger Fehler beim Testen ist, nur die grobe Textrichtung zu prüfen und dabei Detailkomponenten wie Tooltips, Toast-Benachrichtigungen oder Breadcrumb-Trenner zu übersehen, die oft mit fest positionierten, physischen CSS-Werten gebaut wurden und deshalb in RTL an der falschen Stelle erscheinen. Ein systematischer Test-Durchlauf durch alle wiederverwendbaren Komponenten eines Design-Systems deckt solche Lücken zuverlässiger auf als ein einmaliger Blick auf die Startseite.
8. Barrierefreiheit: warum korrekte Bidi-Behandlung auch ein WCAG-Thema ist
Eine falsch angeordnete oder visuell verwirrende Textrichtung ist nicht nur ein optisches Problem, sondern betrifft direkt die Lesbarkeit und damit die Barrierefreiheit einer Seite. Screenreader-Software liest den DOM-Inhalt in der Reihenfolge des Markups vor, unabhängig von der visuellen CSS-Darstellung, weshalb eine per direction nur optisch gespiegelte, aber im Markup nicht angepasste Reihenfolge zu einer für sehende und blinde Nutzer unterschiedlichen, inkonsistenten Erfahrung führen kann.
Die robuste Lösung liegt darin, das dir-Attribut im HTML korrekt zu setzen, statt die Richtung ausschließlich über CSS zu erzwingen, weil Screenreader und andere Hilfstechnologien das dir-Attribut direkt auswerten, während eine rein visuelle CSS-Richtungsänderung ohne entsprechendes Attribut ignoriert wird. :dir() und unicode-bidi ergänzen dieses korrekt gesetzte dir-Attribut um die passende visuelle Darstellung, ersetzen es aber nicht.
9. Praxis-Einsatz im Shop: mehrsprachige Store-Views mit Arabisch oder Hebräisch
Für einen Magento-Shop mit einer arabischen oder hebräischen Store-View lohnt sich eine konsequente Umstellung des Hyvä-Themes auf logical properties als Grundlage, ergänzt um gezielte :dir()-Regeln für Icon-Spiegelungen und unicode-bidi: isolate für alle strukturierten Eingabefelder. Diese Kombination deckt die überwiegende Mehrheit der RTL-Anforderungen ab, ohne dass für jede Store-View ein separates, gespiegeltes Stylesheet gepflegt werden müsste.
Der langfristige Vorteil ist, dass ein so aufgebautes Theme automatisch RTL-tauglich bleibt, auch wenn später eine weitere RTL-Sprache wie Persisch oder Urdu hinzukommt, weil die Logik nicht an eine einzelne Sprache, sondern an die tatsächlich berechnete Textrichtung gekoppelt ist. Ein nachträglich mit physischen Eigenschaften gebautes Theme müsste dagegen für jede neue Richtung erneut manuell überarbeitet werden.
| Technik | Reagiert auf | Typischer Einsatz | Ersetzt JavaScript? |
|---|---|---|---|
:dir(rtl) / :dir(ltr) |
Berechnete Element-Richtung | Icon-Spiegelung, richtungsabhängige Regeln | Ja |
[dir="rtl"] |
Nur explizites dir-Attribut | Einfache, statische RTL-Umschaltung | Teilweise |
unicode-bidi: isolate |
Bidi-Algorithmus pro Element | Eingebettete Zahlen, IBAN, SKU | Ja |
| Logical properties | Aktuelle Schreibrichtung | Abstände, Ausrichtung, Rahmen | Ja |
Mironsoft
Modernes CSS, Layout-Architektur und Rendering-Performance
CSS, das wartbar bleibt statt mit jeder Änderung zu brechen?
Wir prüfen bestehende Stylesheets auf Spezifitäts-Chaos und Layout-Thrashing und bauen daraus eine CSS-Architektur mit Cascade Layers, Custom Properties und modernen Layout-Primitiven, die auch nach dem zehnten Feature noch verständlich ist.
CSS-Audit
Spezifität, Cascade-Konflikte und ungenutzte Selektoren systematisch aufdecken.
Architektur-Refactoring
Cascade Layers, Custom Properties und Design Tokens sauber einführen.
Performance-Tuning
Layout-Thrashing, teure Selektoren und Rendering-Engpässe gezielt beheben.
10. Zusammenfassung
:dir() und unicode-bidi: Das Wichtigste auf einen Blick
Grundprinzip
:dir() reagiert auf die tatsächlich berechnete Textrichtung eines Elements, auch bei dir="auto", und ersetzt damit JavaScript-basierte Richtungserkennung.
unicode-bidi
isolate kapselt eingebetteten Inhalt gegen die Umgebung, plaintext leitet die Richtung komplett aus dem eigenen Inhalt ab, wichtig für Zahlen und nutzergenerierte Texte.
Logical properties
margin-inline-start, padding-inline-end und text-align: start passen sich automatisch an die Schreibrichtung an, ohne eigene :dir()-Regeln.
Icon-Spiegelung
:dir(rtl) mit transform: scaleX(-1) bleibt nötig für richtungsbehaftete Icons wie Pfeile, richtungsneutrale Symbole sollten unverändert bleiben.