Handling mixed-direction text
What the bidi algorithm does
The Unicode Bidirectional Algorithm (UAX #9) decides how text with both directions is displayed. Each character has a direction. Arabic letters run right to left, Latin letters and digits run left to right, and neutral characters such as spaces and punctuation take their direction from the text around them.
This works well most of the time. Problems appear at the boundaries, especially with punctuation next to a Latin word.
Most content problems come from short strings inserted into longer sentences, such as a username in a notification or a file name in a message. Those values arrive from outside, so their direction is not known in advance.
The base direction of a paragraph matters too. It decides which side the paragraph starts on and where neutral characters at the edges end up. This is why setting <code>dir</code> correctly on the page and on each block is the first step.
Latin names, numbers and URLs in Arabic
A brand name such as Figma inside an Arabic sentence is displayed left to right, while the sentence flows right to left around it. If the name is followed by a question mark or a full stop, that punctuation can jump to the wrong side of the Latin word.
Numbers behave in their own way. A phone number or a price is displayed left to right as a unit, but separators such as plus signs, dashes and percent signs are neutral, so they can drift. Wrapping the whole value in one isolated element keeps it together.
The same applies to URLs and to ranges of numbers. Check each such string in context instead of assuming it will look right.
Tools: dir, bdi and isolate
Automatic direction
With <code>dir="auto"</code> the browser picks the direction from the first strong character in the text. Useful for content whose language is unknown.
The bdi element
Wraps a piece of text, such as a username, so its direction does not affect the text around it. It uses auto direction by default.
CSS isolation
The CSS way to isolate an element from its surroundings is <code>unicode-bidi: isolate</code>. Combine it with a direction when you control the markup.
User-generated content and testing
Names, comments and messages written by users can be in any language. Wrap each inserted value in <code><bdi></code> or give it <code>dir="auto"</code> so one Arabic username does not scramble an English sentence, and the reverse.
Do not try to fix bidi problems by inserting invisible control characters into the text unless you must. Markup such as <code>dir</code> and <code><bdi></code> keeps the content clean and is easier to maintain and translate.
- Test real mixed strings: a brand name with a question mark, a price, a phone number, a URL.
- Check the result in both page directions.
- Ask a native reader to confirm the order.
Sources
- Unicode Consortium. Unicode Standard Annex #9: Unicode Bidirectional Algorithm. https://www.unicode.org/reports/tr9/
- W3C. Structural markup and right-to-left text in HTML. https://www.w3.org/International/questions/qa-html-dir
This guide was drafted with AI assistance from public standards and references. For the exact wording of a standard, use the sources listed above.