Bidirectional Text, the Bidi Algorithm, and the bdo
Element
Before I get into an explanation of the bidi algorithm, let's look at a quick example of bdo
as a refresher.
Example 1:
<p>This text appears left-to-right by default, while <bdo dir="rtl">this appears right-to-left</bdo>.</p>
User agents render this as follows:
This text appears left-to-right by default, while tfel-ot-thgir sraeppa siht.
The Why and When of bdo
Each Unicode character has a directionality associated with it—either left to right (like Latin characters in most languages) or right to left (like characters in Arabic or Hebrew). Unicode's bidi algorithm ("bidi" is the abbreviation for "bidirectional") determines how to display content that includes a mixture of both left-to-right and right-to-left characters.
Let's suppose you have a paragraph that's English by default, and you'd like to include a quotation in Hebrew. In most cases, adding dir
and lang
to the surrounding element (not bdo
), as in Example 2, is sufficient, because the bidi algorithm displays the content as intended.
Example 2:
<p>This is English, while <q dir="rtl" lang="he">[your Hebrew content in logical order would be here]</q>.</p>
bdo
comes into play when the bidi algorithm doesn't display it as intended, and you need to override it. When would the algorithm get it wrong? It would get it wrong when the Hebrew content in the HTML source is in visual order rather than logical order.
Visual order is just what it sounds like—the HTML source code content is in the same order in which you want it displayed. Logical order is the opposite for a right-to-left language like Hebrew; the first character going right to left is typed first, then the second character (in other words, the one to the left of it), and so on.
In line with best practices, Unicode expects bidirectional text in logical order. So, if it's visual instead, the algorithm will still reverse the characters, displaying them opposite of what is intended. If you aren't able to change the text in the HTML source to logical order, your only recourse is to wrap it in a bdo
, making the bdo
portion like this:
Example 3:
<p>. . . <bdo dir="rtl" lang="he">. . .</bdo> . . .</p>
The lang
attribute declares the language but does not dictate the directionality, which is why dir
is always required.
So, in summary, always put bidirectional content in logical order when possible so you can avoid having to resort to using bdo
.
If you'd like to learn more about the bidi algorithm and right to left text directionality, the W3C's article, "Creating HTML Pages in Arabic, Hebrew and Other Right-to-left Scripts" discusses it at length.
NOTE: If you try Example 2 exactly as it's written, the English phrase "[your Hebrew content in logical order would be here]" will not display right-to-left. That's correct behavior per the bidi algorithm because the characters are English. If you replace the text with Hebrew in logical order, it should display right to left.