:dir() und unicode-bidi: mehrsprachige Layouts ohne JavaScript steuern
AI generated
{ }
@
CSS · Internationalisierung · RTL · Barrierefreiheit
:dir() und unicode-bidi
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.

14 Min. Lesezeit :dir() · unicode-bidi · logical properties Chrome · Firefox · Safari (aktuell)

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.

11. FAQ: :dir() und unicode-bidi: Das Wichtigste auf einen Blick

1Was ist der Unterschied zwischen :dir() und [dir="rtl"]?
[dir="rtl"] matcht nur ein wörtlich gesetztes dir-Attribut. :dir(rtl) reagiert auf die tatsächlich berechnete Richtung, auch wenn diese über dir="auto" oder Vererbung zustande kommt.
2Wann sollte ich unicode-bidi: isolate verwenden?
Immer dann, wenn ein Element wie eine Artikelnummer, IBAN oder URL innerhalb von Text mit anderer Schreibrichtung eingebettet ist und nicht von der umgebenden Richtung beeinflusst werden soll.
3Was macht unicode-bidi: plaintext anders als isolate?
plaintext leitet die Richtung eines Elements komplett neu aus dessen eigenem Inhalt ab, unabhängig vom Elternelement. Das eignet sich besonders für nutzergenerierte Kommentare mit unbekannter Sprache.
4Reicht dir="rtl" auf dem html-Element nicht aus?
Für die grobe Seitenrichtung ja, aber einzelne Elemente wie Produktcodes oder mehrsprachige Kommentare brauchen oft eine eigene, abweichende Richtung, die sich nur über :dir() oder unicode-bidi gezielt steuern lässt.
5Muss ich alle Icons in RTL spiegeln?
Nein, nur Icons mit tatsächlicher Richtungsbedeutung wie Pfeile oder Chevrons. Richtungsneutrale Symbole wie ein Warenkorb- oder Uhr-Icon sollten unverändert bleiben.
6Was sind logical properties und warum brauche ich sie für RTL?
Logical properties wie margin-inline-start richten sich relativ zur aktuellen Schreibrichtung aus statt an einer festen Bildschirmseite, wodurch ein Layout automatisch in LTR und RTL korrekt aussieht.
7Wie teste ich ein RTL-Layout, ohne die Sprache umzustellen?
dir="rtl" testweise im DevTools-Elementinspektor auf das html-Element setzen zeigt das gespiegelte Layout sofort, ganz ohne Wechsel der Systemsprache oder Store-View.
8Sollten IBAN-Nummern in einem RTL-Formular gespiegelt angezeigt werden?
Nein. Strukturierte Formate wie IBAN oder Telefonnummern sollten mit direction: ltr und unicode-bidi: isolate immer in ihrer festen internationalen Notation bleiben, unabhängig von der Seitenrichtung.
9Funktioniert :dir() auf jedem beliebigen Element?
Ja, die Pseudoklasse lässt sich auf jedes Element anwenden, nicht nur auf html oder body, was sie auch für einzelne, gemischt-sprachige Komponenten innerhalb einer Seite nutzbar macht.
10Was passiert, wenn ich weder :dir() noch logical properties verwende?
Physische Eigenschaften wie margin-left ignorieren die Textrichtung komplett, wodurch ein RTL-Layout ohne Anpassung schlicht falsch aussieht: Abstände und Ausrichtung sitzen dann durchgehend auf der falschen Seite.