A bidirectional embedding level is a nonnegative integer used by the Unicode Bidirectional Algorithm to represent directional nesting. A level whose value is an even integer has left-to-right embedding direction; one whose value is an odd integer has right-to-left embedding direction.[ref]
Level values carry more information than parity. For example, levels2 and4 share the same default direction, but they participate differently in level-based reordering of bidirectional text. Higher values indicate more deeply nested directional structure, rather than a greater physical displacement across the screen.
An original supplied-level example uses the list
The level4 pass reverses . The level3 pass reverses that same pair again, the level2 pass reverses it a third time, and the level1 pass reverses the larger middle run. The final physical left-to-right list is . If the intermediate level3 pass were omitted merely because no item had level3, the middle pair would come out in the opposite order.
These are supplied resolved levels for an algebraic illustration, not a claim that arbitrary level arrays arise from any particular unformatted string. Resolving levels from Unicode bidirectional classes, explicit controls and context is an earlier part of the algorithm. The final reversal stage consumes those results.[ref]
A level also differs from a character's original property. A decimal digit can be assigned a level within a surrounding directional context without becoming a different stored code point. Keeping the property, the computed level and the eventual display position separate makes implementation traces easier to check.
Bidirectional isolate 2026-11-05
A bidirectional isolate is a span treated as a directional unit by the Unicode Bidirectional Algorithm. Its internal text is resolved separately from the surrounding text; the isolate as a whole behaves neutrally in its surroundings. This limits directional interaction when inserting a span whose contents have their own writing direction.[ref]
Unicode directional controls can delimit the span: LRI (U+2066) chooses left-to-right isolation, RLI (U+2067) chooses right-to-left isolation, FSI (U+2068) infers direction from the first relevant strong character, and PDI (U+2069) terminates the isolate. Higher-level markup can express equivalent isolation without storing those explicit control characters.[ref]
An original record-layout example has three fields: a fixed prefix, a user-supplied name and a fixed suffix containing punctuation and an identifier. Treat the inserted name as one isolated span. The outer layout then works with that span as a unit, while its contents receive their own directional processing. A name containing both letters and digits still needs internal reordering; isolation does not prescribe a reversal of every character inside it.
For a reproducible plain-text notation, write the sequence as prefix RLI payload PDI suffix, with the uppercase labels standing for control code points rather than literal letters in the displayed text. This notation documents the boundary without hiding directional controls in the source example. An actual test should record the concrete payload, paragraph direction, Unicode version and line boundaries as well.
Nesting introduces another distinction: a first-strong isolate determines its direction from an eligible strong character outside nested isolates. A direction already enclosed in a nested span need not choose the enclosing span's direction. Naming the span boundary and the rule used to choose its direction makes this behavior explicit.[ref]
CSS inline direction 2026-11-05
The CSS inline direction is the base directionality used for text within a line and for related direction-dependent layout. The direction property selects ltr or rtl; together with CSS writing mode, this establishes the mapping of logical inline-start and inline-end to physical directions.[ref]
For a horizontal example with ordinary start-aligned text, direction: ltr places inline-start at the left edge, while direction: rtl places it at the right. A label aligned to inline-start can consequently change sides without changing its source text. In vertical writing, interpreting inline-start requires the writing-mode mapping too; it is not always a physical left or right edge.
Base direction is not an instruction to reverse every letter. The Unicode Bidirectional Algorithm considers the directional properties of text and the surrounding embedding or isolation context. A left-to-right sequence such as ABC can retain its internal order inside a right-to-left paragraph. CSS uses that algorithm rather than treating a string as an undifferentiated list to reverse.[ref]
For HTML, the specification recommends expressing a document's directional semantics with markup such as <p dir="rtl">ABC</p> instead of depending solely on a CSS override. That example establishes a right-to-left paragraph base; it does not promise the visible sequence CBA. Keeping the directional information in the document also preserves it when styling is unavailable.[ref]
CSS block flow direction remains a separate choice. A right-to-left horizontal paragraph still participates in a top-to-bottom block flow under horizontal-tb. Conversely, vertical lines can progress across a page under the block rules while their inline base direction follows its own mapping.
The scope of an override matters as well. A direction declaration on an ordinary inline box with unicode-bidi: normal does not by itself open a new embedding level for reordering. Diagnose the box's direction, its writing mode and the relevant bidirectional scope together.[ref]
Level-based reordering of bidirectional text is the final positional reversal procedure of the Unicode Bidirectional Algorithm after directional levels and line boundaries have been resolved. RuleL2 processes thresholds from the largest level down through the smallest level whose value is an odd integer. Each pass reverses every maximal consecutive run whose levels meet or exceed the threshold.[ref]
An original trace supplies the resolved levels rather than attempting to infer them. Take the logical items
At threshold2, reverse only the two middle digits, obtaining . At threshold1, reverse the entire middle five-item run, giving
The digits underwent two reversals, preserving their internal order. The labels each denote one abstract right-to-left text character; every array is written in physical left-to-right order.
Figure 1.
Descending level passes reverse nested runs and restore the internal order of digits
. Reused supplied-level illustration. It demonstrates ruleL2, rather than a complete implementation that resolves levels, shapes glyphs or chooses line boundaries. Details.
Thresholds include intermediate values that no item happens to have. For example, a pair at level4 surrounded by level1 items participates in passes4,3,2 and then the enclosing pass1. Omitting pass3 changes the result, as the bidirectional embedding level example demonstrates.
An implementation may carry levels with the items, as the figure generator does. It can also locate each reversal range from the original fixed level array: earlier passes permute items only inside higher-level runs, preserving the boundaries of every later lower-threshold run. Keeping logical indices on the displayed items supplies the eventual position map. Line-final whitespace resetting belongs to ruleL1, and combining-mark handling and mirroring require their separate rules.[ref]
Logical text order 2026-11-05
Logical text order is the order in which text characters are represented in a stored sequence for interpretation. A bidirectional renderer derives visual text order from that sequence; it does not require the stored characters to be prearranged in screen-position order.[ref]
An original indexing example uses six abstract items. Write the stored positions in order as
The labels each stand for a single right-to-left text character. All displayed arrays here are read physically from left to right. Applying level-based reordering of bidirectional text to these supplied levels gives the visual list , whose source-position list is . Stored position1 remains position1 even though its item is drawn near the right end.
This distinction makes a text-processing task precise. An operation on logical positions1 through4 selects the contiguous stored subsequence . A renderer may need a position map to relate that range to its displayed cells. Sorting characters by screen coordinate before searching or serializing the text would change the sequence being processed.
Logical order does not determine a font's glyph geometry. Text shaping, line layout and the Unicode Bidirectional Algorithm contribute different information. For example, a different line break can change which items are reordered together while the underlying stored sequence remains the same.[ref]
Mark Davis is a computer scientist whose work connects Unicode specifications with practical software internationalization. The Unicode Consortium's2023 workshop profile credits him with co-founding the Unicode project, leading the architecture of International Components for Unicode and founding the Common Locale Data Repository. It records his presidency of the Consortium from1991 through2022.[ref]
Figure 1.
Mark Davis, from his labeled official Unicode Technology Workshop2023 speaker portrait
.
One specific contribution is the Unicode Bidirectional Algorithm: its acknowledgments identify Davis as creator of the initial annex and maintainer of its text through2023. The algorithm computes visual text order from logical text order, allowing differently directed writing systems to coexist in one represented sequence.[ref]
A small original example illustrates the kind of interoperability problem this work addresses. If a line has a right-to-left name next to the digits12, reversing every stored character would turn those digits into21. A direction-sensitive algorithm can reorder surrounding runs while preserving the digits' internal order. Its exact result depends on resolved bidirectional embedding levels and context, rather than a single whole-string reversal.
The specification and the implementation libraries address complementary parts of the problem. A shared algorithm states what independent renderers should compute; reusable internationalization software helps applications apply such behavior consistently. The Common Locale Data Repository supplies another kind of shared resource for locale-sensitive software. These contributions concern data representation and reproducible processing, rather than assigning one fixed glyph shape to every code point.
The Unicode Bidirectional Algorithm computes visual text order from logical text order. Unicode bidirectional classes and context determine bidirectional embedding levels: levels with an even integer value run left-to-right, and those with an odd integer value run right-to-left. Stored code points retain their order; text shaping is separate.[ref]
After levels and line boundaries are resolved, level-based reordering of bidirectional text descends from the largest level to the smallest level that is an odd integer. Each pass reverses maximal consecutive runs at or above its level.[ref]
Here is a small example with the resolved levels supplied. The labels each represent a distinct right-to-left text character, while represent left-to-right text characters. All rows below are written in physical left-to-right order. Start with
The level 2 pass changes the middle digits to . The level 1 pass then reverses the whole five-item middle run, producing
The digits have been reversed twice, preserving their original internal order. Reversing the entire stored sequence once would instead exchange and and leave the digits in the wrong order. This example demonstrates the reordering step, not how all Unicode bidirectional classes are resolved.
Figure 1.
Two level-based reversals preserve the internal order of the digits
. Original illustration with supplied bidirectional embedding levels. The boxes denote individual abstract text characters, not literal multi-character labels. Details.
A bidirectional isolate limits directional interaction between inserted text and its surroundings. Markup can express isolation without storing explicit formatting code points.[ref]
Mark Davis created the annex's initial version; later revisions extended it.[ref]
A Unicode bidirectional class is a character property, formally named Bidi_Class, used as input to the Unicode Bidirectional Algorithm. It classifies directional behavior; the algorithm combines the properties with context to compute bidirectional embedding levels. A class is not itself a final screen position.[ref]
For a compact example, Latin A (U+0041) has classL, Hebrew alef (U+05D0) has classR, digit1 (U+0031) has classEN, and ordinary space (U+0020) has classWS. These labels distinguish strong directions, a numeric class and whitespace. They carry information that a single left-to-right/right-to-left Boolean would lose.
An original data-structure example keeps the stages separate. Represent each stored item by a record containing its logical index, code point, original Bidi_Class, working directional type, resolved level and eventual visual index. A direction-resolution step can update the working fields while leaving the stored code point and original property intact. A later level-based reordering of bidirectional text step changes position mappings rather than assigning new code points.
The advantage appears in debugging a digit within mixed-direction text. Its original classEN identifies a numeric input. Its resolved level describes the computed directional context, and its visual index identifies a placement in one line. Reporting only the visual index would conceal whether a mistake arose during classification, context resolution or final reordering.
The normative property data are supplied by the Unicode character database; broad descriptions such as “a letter in this script” have exceptions. An implementation should use the data for its chosen Unicode version rather than infer every character's class from appearance.[ref]
A Unicode directional control is a formatting code point that affects bidirectional processing without contributing an ordinary visible letter. Directional marks, embeddings, overrides and isolate delimiters provide different mechanisms within the Unicode Bidirectional Algorithm. They affect interpretation of the stored sequence rather than supplying new letter shapes.[ref]
Left-to-right and right-to-left marks, LRM (U+200E) and RLM (U+200F), behave as strong directional items while remaining invisible. A right-to-left isolate initiator, RLI (U+2067), instead starts a bounded bidirectional isolate; PDI (U+2069) terminates it. A mark and a span delimiter therefore carry different structural information.[ref]
An original counting example documents controls by their numerical values. The sequence U+2066 U+0061 U+0062 U+2069 contains LRI, the two Latin letters a and b, and PDI. It contains four code points and eight UTF-8 bytes: three for each delimiter and one for each Latin letter. Its ordinary visible letters are just a and b. Counting visible letters would therefore lose information about the represented sequence.
This notation intentionally shows the control values instead of placing hidden directional formatting characters in the source example. To reproduce an actual layout test, record its logical text order, paragraph direction, Unicode version and line boundaries, then compare the computed bidirectional embedding levels and visual text order.
A higher-level format can express equivalent directional structure through markup. The control-code-point representation and the markup representation need not have the same stored characters even when they request corresponding layout behavior. The specification defines those correspondences, while text shaping remains a further part of rendering.[ref]
Visual text order 2026-11-05
Visual text order is the ordering of displayed text items within a rendered line. In bidirectional text it can differ from logical text order, the stored character sequence. It describes a presentation result, so the line boundaries and resolved directional information belong to its context.[ref]
For an original permutation example, take six logical items with supplied levels . The resulting left-to-right display positions contain source indices
Thus the displayed items are . The digits keep their internal order even though the surrounding right-to-left items exchange physical positions. A single reversal of the whole stored list would give a different result.
A position map preserves information that a picture alone may lose. If two source items both display as the same letter, their appearances do not reveal which logical index each came from. A renderer can retain distinct indices while drawing identical shapes. Likewise, interpreting a pointer position as a text location requires more information than simply treating a visual column number as a logical index.
The Unicode Bidirectional Algorithm orders text items, while text shaping determines additional glyph forms and combinations. Distinguishing these stages prevents a permutation of character positions from being mistaken for a complete specification of glyph geometry.[ref]
Visual order is therefore useful for describing what appears on a particular line, while logical text order supplies stable positions for the represented sequence. Reporting both orders and their mapping makes an example reproducible without assuming that the reader's own browser will display a mixed-direction string in the intended way.