What is RTL testing?
Learn what RTL testing checks, how it differs from translation review, which failures it finds and how to run a useful first test pass.
Guide14 min read
RTL testing verifies that an interface works when its base direction runs right to left. For an Arabic product, that includes document direction, mixed Arabic and Latin text, direction-sensitive layout, forms, local formats, typography, keyboard order and dynamic states.
It is not a check that the screen looks like a horizontally flipped English version. A page can look mirrored while a promotion code reads backward, an email field edits from the wrong edge, the tab sequence jumps across the screen and an error dialog stays in English. RTL testing finds those failures and traces each one to the layer that owns it.
The shortest useful definition is this: translation testing asks whether the words are right; RTL testing asks whether the interface around those words behaves in the right direction. A complete Arabic release needs both.
What RTL testing covers#
RTL behavior crosses several parts of the browser and application. A meaningful test pass covers these areas:
| Area | Question the test answers | Example failure |
|---|---|---|
| Document setup | Does the Arabic page declare its language and base direction? | Arabic copy renders under an LTR root |
| Bidirectional text | Do Arabic, Latin text, digits and punctuation stay readable together? | A promotion code 50-OFF displays as OFF-50 |
| Layout | Do start and end relationships follow direction? | A field icon overlaps text after moving sides |
| Typography | Does Arabic shape and fit with the intended font? | Tracking separates connected letters |
| Formats | Do dates, digits, currency and units match the market rule? | A Saudi price uses the wrong currency format |
| Forms | Does each field use the direction appropriate to its data? | An email field edits RTL |
| Interaction | Does focus follow a logical task order? | Tab order fights visually reversed controls |
| Dynamic content | Do errors, menus and loaded data still work? | A server message overflows after submission |
These are related, but they are not one bug class. Changing direction: rtl cannot translate a validation message, isolate a phone number, select the right calendar or repair DOM order. Good RTL testing first identifies which behavior failed, then fixes that layer.
The scope also extends beyond visible body content. Page titles, social metadata, image alternatives, tooltips and accessible names can remain in the source language even when the main interface is Arabic. Locale routing can lose Arabic after authentication or a redirect. For a public website, language alternatives and canonical URLs can point to the wrong locale. Those are release failures even if the screenshot appears correct.
Where RTL defects actually come from#
"RTL bug" describes the surface, not the cause. The same visible symptom can originate in different layers, and the repair belongs where the assumption was introduced.
| Symptom | Inspect first | Typical cause | Better repair |
|---|---|---|---|
| Whole page aligns incorrectly | Live root attributes | Missing or stale dir after routing | Set semantic direction at the document boundary |
| One code or number reorders | Markup around the value | No bidi isolation | Isolate the value, not the whole component |
| Icon overlaps input text | Computed offsets and padding | Physical CSS assumes LTR | Use logical inset and padding properties |
| Arabic label clips | Font, width and overflow | Fallback metrics or fixed dimensions | Provide Arabic-capable fonts and content-driven sizing |
| Email field edits backward | Input type and computed direction | Field inherited RTL | Give inherently LTR data an LTR field direction |
| Price looks foreign | Formatter locale and options | Wrong currency or implicit locale default | Encode the market rule in formatter options |
| Keyboard jumps across controls | DOM, flex order and tabindex | Visual reversal without structural review | Restore a logical DOM sequence |
| English appears after failure | Response and translation source | Error state bypasses the Arabic catalog | Localize the producing service or state |
This classification changes how teams debug. If an Arabic alert clips, shortening the translation may make the current screenshot pass, but the fixed-height component will fail again with another message. If a promotion code displays reversed, reversing its characters in code can make the screen look right while copy and paste and screen readers get the reversed code, because both follow the source.
The quickest diagnostic method is reduction. Keep the same locale and data, then remove surrounding layout until the text or control still fails. If the code reorders in a plain right-to-left paragraph, the problem is bidi context rather than grid placement. If it becomes correct outside the component, inspect inherited direction, generated content and sibling punctuation. For layout, compare computed values in LTR and RTL, then identify the first physical property whose meaning should have been logical.
Dynamic timing is another source. The initial server document may be Arabic and RTL, then client state replaces the root attributes. A loading placeholder may fit while the resolved Arabic label overflows. A web font may change the bounding box after a screenshot was captured. An error returned by a backend may never pass through the client translation system. Test the state transition, not only its final mockup.
Shared code determines the size of the fix. A physical spacing token can create the same defect in dozens of components. A formatter helper can spread one currency mistake across UI, email and export. When several reports share a pattern, repair the primitive and add the regression there before applying route-level overrides.
This is one reason RTL testing belongs in ordinary engineering QA. The defects are rarely confined to a special Arabic stylesheet. They expose assumptions about text, layout, data and interaction that live in the same components used by the rest of the product.
RTL testing is not translation review#
Translation review evaluates meaning, grammar, terminology, tone and market suitability. RTL testing evaluates direction, rendering, layout and interaction. The two practices overlap in the running product, but one cannot replace the other.
Consider a translated checkout error. The Arabic sentence may be linguistically accurate while:
- the application never loads it for the payment-rejection state;
- its order number reorders inside the sentence;
- the second line is clipped by a fixed-height alert;
- the alert icon remains anchored to the wrong side;
- focus stays on the submit button instead of reaching the error;
- an English accessible label remains on the retry button.
An Arabic reviewer can identify the language issue and judge whether the complete message reads naturally. A QA engineer who does not read Arabic can still reproduce the state, verify that the translated key resolved, inspect the value's character order, measure clipping and test focus. The work is strongest when those roles have explicit boundaries.
Do not ask translation to compensate for engineering defects. Shortening a correct label until it fits a fixed-width button hides a sizing problem. Adding spaces around a phone number to influence display order hides a bidi problem. Changing word order to match a concatenated English template hides a message-composition problem.
The reverse mistake is treating every Latin token as untranslated. Email addresses, URLs, product models and approved brand names may intentionally remain Latin. The test needs content rules, not a blanket ban on Latin script. R010 reports visible Latin-script body text above its thresholds, while R011 and R012 cover untranslated interactive labels and attribute text. A human still decides whether a particular term is intentional.
The browser does not mirror a bitmap#
The root of an Arabic document declares its language and its direction, and the two are independent: lang="ar" does not make a page right to left, and right to left does not identify Arabic. The HTML dir attribute is inherited by descendants that do not declare their own direction, and it drives text alignment, the order of directional runs and direction-aware layout.
The quickest check is the console on the live page:
document.documentElement.lang; // "ar"
document.documentElement.dir; // "rtl"
getComputedStyle(document.documentElement).direction; // "rtl"If dir is empty while the computed direction is rtl, a stylesheet is doing the attribute's job. The page looks right, but styles written against :dir(rtl) do not match it. R001 reports an Arabic page whose root direction is missing or LTR. R002 reports a missing, non-Arabic or contradictory language declaration.
After setting dir, the browser maps direction-aware behavior. An RTL flex row begins from the right under its normal row flow. Text aligned to start uses the right edge for RTL content. Logical properties such as padding-inline-start map according to direction. None of this means every visual object should flip. A clock face or a brand mark keeps its own shape whatever the page language.
Bidirectional text is the part most teams underestimate#
Arabic interfaces contain LTR data all the time: phones, emails, URLs, product names and codes. The browser does not keep each substring visually frozen. It resolves characters using the Unicode Bidirectional Algorithm. Arabic letters, Latin letters, digits and punctuation participate with different directional classes.
That is why superficially similar values behave differently. Measured in Chromium 151, a promotion code that starts with letters, such as SAVE-50, stays intact after Arabic text, while one that starts with digits, such as 50-OFF, displays as OFF-50, even with no Arabic before it. The letters at the start give the first code a strong left-to-right run; digits at the start have no direction of their own.
Problem
<p dir="rtl">رمز الخصم 50-OFF</p>An Arabic reader expects the label to read right to left and the code to look exactly as it did in the campaign email. Reversing the string in application code is the wrong repair: copy and paste follows the source, so a customer who copies the code would paste OFF-50 at checkout.
Better
<p dir="rtl">رمز الخصم <span dir="ltr">50-OFF</span></p>A code has a known direction, so dir="ltr" states it. For a value whose direction is unknown, such as a customer's name, <bdi> takes the direction from the value itself. The W3C guidance on inline bidi markup recommends tightly wrapping an opposite-direction phrase so adjacent punctuation and numbers do not become part of the wrong run.
R021 reports unisolated phone numbers, emails and Latin tokens inside Arabic text. How hyphenated numbers reorder, and how to test for it, is covered in RTL testing: the complete guide.
Layout testing checks relationships, not symmetry#
A useful RTL comparison asks whether relationships remain correct. Inline-start navigation should stay at inline start. A suffix icon should stay at the suffix edge. A primary action should keep its hierarchy. An element that represents a physical direction should keep that physical meaning.
Physical CSS often reveals where the component assumed English:
Problem
.product-card .badge {
position: absolute;
top: 8px;
right: 8px;
}Better for a badge anchored to the end corner
.product-card .badge {
position: absolute;
top: 8px;
inset-inline-end: 8px;
}The CSS logical-properties model expresses positions relative to writing direction. This reduces locale-specific overrides and makes the intent visible in code.
Physical properties are not inherently wrong. The mistake is using them for a logical relationship without an RTL counterpart. Review margins, padding, offsets, borders, corner radii, floats, shadows and text indents. Transforms have no logical form, so a panel that should slide in from the end edge needs its direction chosen in code.
Do not add row-reverse simply because a component needs RTL. A normal flex row already responds to an RTL container. Reversing it again can create a screen that looks acceptable while its DOM and tab order remain at odds with the visual task. R081 reports flex reversal used to imitate RTL.
Directional icons need semantic decisions. The back chevron in a mobile header follows the reading direction; a camera, a clock or a logo does not. R025 reports a directional icon that points against the way its control moves, such as a "next" arrow pointing back, which is a useful prompt to inspect the action rather than flip every asset.
RTL testing includes content pressure#
Real Arabic text changes component size. Font metrics, connected glyph shapes, line wrapping and translation length expose failures that a flipped English fixture cannot.
Test the narrowest supported viewport, intermediate widths where flex items wrap, and a wide layout. Increase text size or zoom to 200 percent. Load the longest real labels, open dialogs and menus, trigger multiline validation, and wait for asynchronous data and web fonts.
Look at the left viewport edge as deliberately as the right. Physical offsets often push RTL content leftward. Compare document scrollWidth with clientWidth, then inspect the bounding box of any element that escapes its container. Do not reach for overflow-x: hidden on the body: it removes the scrollbar, not the element hanging off the edge.
R040 reports document-level horizontal overflow. R041, R042 and R043 cover overlapping text, clipped content and fixed-width containers exceeded by Arabic text.
Typography deserves a separate check, covered in RTL testing: the complete guide: Arabic letters join, so tracking designed for Latin headings pulls words apart, and a font without Arabic glyphs hands the text to a fallback face. R050, R051 and R055 report font fallback, positive tracking and Latin display styling applied to Arabic.
Forms are not uniformly RTL#
An Arabic form generally places its labels, help text and ordinary prose fields in RTL. The values inside phone, email, URL and code fields often remain LTR. Treat direction as a property of the field's data, not only of the page. A sign-in form is the smallest example:
<form lang="ar" dir="rtl">
<label for="login-email">البريد الإلكتروني</label>
<input id="login-email" name="email" type="email" dir="ltr" autocomplete="username">
</form>Without its own dir, the email field would inherit right to left from the form, although every address is typed left to right. Choosing a semantic input type does not settle this: only type="tel" is left to right by default.
Test editing, not just the empty box. Paste a complete value, move the caret through punctuation, select a middle range, delete and type at each end. Check prefix and suffix icons, placeholder alignment, clear controls and error messages. R070 reports telephone, email and URL controls rendered RTL. R023 reports text inputs rendered LTR where Arabic input is expected.
Trigger native and application validation too. The browser's own validation messages do not follow the page's lang, so if Arabic validation is required, provide and test localized application messages. R071 reports untranslated labels, validation and help text.
Formats require a market rule#
RTL direction does not choose the right numbering system, calendar, date order or currency. Those are locale and product decisions. ar-SA and ar-AE format the same number with different digits by default, and those defaults come from locale data that changes, so the product decides and passes numberingSystem and calendar to Intl explicitly; RTL testing: the complete guide shows the options.
Test a day above 12, month names, decimals, thousands, negative amounts, zero and percentages. Check the same value in cards, tables, filters, emails, exports and receipts because those surfaces often use different formatting paths.
R060, R061, R062 and R063 report common date, digit, currency and percent or unit inconsistencies.
Visual order is not keyboard order#
CSS can move an element without moving it in the DOM. Keyboard focus normally follows document order, and assistive technology also depends on document structure. A mirrored toolbar can therefore look right while focus jumps in a sequence that no longer matches the task.
Focus does not have to trace every pixel from right to left: the WCAG focus-order guidance asks for an order that preserves meaning and operation. Two independent columns may allow more than one logical order. A search field and its submit button have a clearer task relationship.
Test without a pointer. Press Tab through navigation and the main action, use arrow keys inside composite controls, open and close a dialog, submit invalid data and check where focus moves. Keep focus visible. Avoid positive tabindex as a repair for visual reordering; it creates another order that becomes fragile when responsive or conditional controls appear.
Inspect accessible names as well. A translated icon button can still expose an English aria-label. Intentional foreign-language phrases may need a matching lang attribute for correct pronunciation. R012 reports untranslated attribute text, and R080 reports foreign-language runs with no language annotation.
Manual and automated tests answer different questions#
Automation is good at invariants:
- the Arabic route renders with the expected
langanddir; - critical controls have translated names;
- known field types have the intended direction;
- selected viewports have no unexpected document overflow;
- number and date formatters use required options;
- focus follows a defined critical-task sequence;
- high-value components match reviewed visual states.
Human review is needed for language quality, whether an English term is intentional, whether an icon's meaning reverses, whether mixed text is readable to an Arabic user and whether the complete task still makes sense.
A screenshot test can catch a moved button, but it cannot tell whether a code on screen is the real value or a string reversed in code to look right. A DOM assertion can confirm dir="rtl" but cannot judge whether an Arabic heading is clipped after its font loads. Layer the evidence instead of expecting one test type to certify the interface.
A Ritla scan runs every check against the rendered page and names the element involved, so a finding leads to the exact product state and owning layer, not to a generic "RTL" ticket.
How to run a first RTL test pass#
Choose one critical journey that contains navigation, mixed data, a form and a completion state. Checkout, account creation or order lookup works better than a static homepage.
- Open the Arabic URL directly. Inspect the live root for
lang="ar"anddir="rtl". Refresh and navigate without a full reload to confirm they persist. - Check visible and hidden translation surfaces. Include buttons, errors, placeholders, tooltips, alternative text and accessible labels.
- Load hostile mixed values. Use a code that starts with digits, one that starts with letters, a phone number with a country code, an email address, a URL, a percentage and a negative amount.
- Change the viewport. Test narrow, intermediate and wide widths, then zoom. Open menus, dialogs and error states after fonts and data load.
- Edit every field. Type Arabic prose, a phone number and an email. Move the caret, paste, delete, trigger validation and correct the values.
- Verify formats. Check date order, digit system, calendar, currency and percent placement against the product's market contract.
- Use only the keyboard. Follow focus through the task, operate composite widgets and confirm overlay focus behavior.
- Compare with LTR by relationship. Check that start and end roles, hierarchy and physical meaning remain correct rather than demanding geometric symmetry.
- Route each defect to its layer. Document direction, bidi boundary, layout rule, font, formatter, form control, content source or DOM order.
- Add a focused regression test. Preserve the smallest fixture that would catch the same failure next time.
For a compact version to use during a release, follow the RTL testing checklist for Arabic websites.
FAQ
If the page is mirrored, is RTL testing finished?
No. Mirroring does not verify bidi values, forms, formats, font fallback, focus order, untranslated states or locale routing. It is one visual property of the complete interface.
Does lang="ar" automatically make the page RTL?
No. Language and direction are separate. Set dir="rtl" on the Arabic document and verify the live DOM after navigation.
Should every icon flip?
No. Flip meaning that reverses with reading or navigation direction. Keep physical, brand and intrinsic symbols unchanged unless their design specification says otherwise.
Should every field be RTL on an Arabic page?
No. Arabic prose fields usually use RTL. Phone numbers, emails, URLs and many codes remain LTR. Test each field according to its data.
Can a team test RTL without an Arabic speaker?
It can find many engineering defects without one: missing direction, overflow, physical CSS, field direction, focus order and known-value corruption. It cannot approve grammar, tone, terminology or market suitability. Both kinds of review are required for a complete Arabic release.
Checks in this guide
- R010Visible Latin-script body text above thresholds on an Arabic page
- R011Untranslated interactive labels (buttons, nav/footer links, menu items, tabs)
- R012Untranslated attribute text (placeholder, alt, title, aria-label, button value)
- R001document direction missing, contradicted, or declared only in CSS
- R002html[lang] missing, non-Arabic, or contradicting detected content
- R021Unisolated bidi hazards: phones, emails, Latin tokens inside Arabic text
Show every check in this guideShow fewer
- R081flex row-reverse faking RTL instead of dir (tab order fights visual order)
- R025Directional icon pointing against the sequence its control advances
- R040Document-level horizontal overflow
- R041Visible text-bearing elements overlapping
- R042Clipped text: content wider than its box with overflow hidden and no ellipsis
- R043Fixed-pixel-width container whose Arabic text exceeds the space
- R050Arabic text falling back past the declared font family (measured, declared, or a webfont that failed to load)
- R051letter-spacing applied to Arabic text (breaks the connected script)
- R055Latin display styling (uppercase + tracking) applied to Arabic
- R070tel/email/url inputs rendered RTL (these must stay LTR)
- R023Text inputs rendered LTR where Arabic input is expected
- R071Untranslated form labels / validation / help text
- R060English month/day names or MM/DD/YYYY dates in Arabic text
- R061Arabic-Indic and Western digits mixed in the same context
- R062Foreign currency formatting in a SAR/AED market context
- R063Percent/unit ordering inconsistencies (%50 vs 50%)
- R080Intentional foreign-language runs missing a lang attribute