Text Direction: dir, bdo, and bdi
Not every language reads left to right. Arabic, Hebrew, Persian, and Urdu all read right to left (RTL), and HTML has built-in support for handling direction correctly — the dir attribute, plus two specialized elements, <bdo> and <bdi>.
The dir Attribute
dir is a global attribute — it can go on any element — and it tells the browser which way text should flow.
Value | Meaning |
|---|---|
ltr | Left-to-right (default for most languages, e.g. English) |
rtl | Right-to-left (Arabic, Hebrew, Persian, Urdu, etc.) |
auto | Browser inspects the text content and guesses the direction |
dir.html
<html lang="ar" dir="rtl">
<body>
<p>مرحبا بكم في دورة HTML</p>
</body>
</html>
<!-- Mixed page: one paragraph flips direction -->
<p dir="rtl">שלום עולם</p>dir="rtl" on the <html> element alongside the matching lang attribute (e.g. lang="ar"). Browsers then mirror the whole layout — scrollbars, alignment, even some CSS flex-direction behavior follows along automatically.<bdo> — Overriding Direction
<bdo> (Bi-Directional Override) forces a specific piece of text to render in a given direction, overriding whatever direction the browser would otherwise choose. It requires a dir attribute.
bdo.html
<p>Normal text, then reversed: <bdo dir="rtl">This will display backwards</bdo></p>
<bdo> is a niche tool — mostly used for deliberately demonstrating direction override (like the example above) or handling unusual typographic requirements. For normal RTL content, plain dir="rtl" on a container is almost always the right tool.<bdi> — Isolating Direction
<bdi> (Bi-Directional Isolation) is the practical one. It isolates a span of text so its direction doesn't leak into — or get messed up by — the surrounding text. This matters most for user-generated content, where you don't control the language or direction of a name, username, or comment.
bdi.html
<ul> <li><bdi>user_علي</bdi>: 42 points</li> <li><bdi>Sarah_2024</bdi>: 17 points</li> </ul>
<bdi>, the surrounding LTR punctuation (like the colon and number after it) can visually reorder in confusing ways. <bdi> prevents that leak without you needing to know each user's language ahead of time.RTL Language Support Checklist
Set lang and dir="rtl" together on <html> for fully RTL pages (e.g. lang="ar" dir="rtl").
Wrap user-generated snippets of unknown direction in <bdi> so they can't distort surrounding layout.
Use logical CSS properties (margin-inline-start instead of margin-left) so spacing flips correctly in RTL.
Test icons and arrows — directional icons (like a "next" chevron) often need to be mirrored for RTL layouts.
Quick Reference
Feature | Scope | Use case |
|---|---|---|
dir attribute | Any element (global) | Set base direction of content |
<bdo> | Element | Force/override direction for a span |
<bdi> | Element | Isolate unpredictable direction (user content) |