Skip to content

RTL navigation: the complete guide

Build RTL navigation with coherent link order, dropdown placement, breadcrumbs, directional controls and keyboard behavior across screen sizes.

By , Founder of Ritla

Guide14 min read

A navigation bar can look Arabic while its interaction remains tied to an English layout. The first link appears at the right, but keyboard focus begins at the opposite end. A dropdown opens beyond the screen. A back arrow points forward even though its label names the previous destination.

These failures need separate fixes. Text direction, item sequence, popup positioning and directional meaning are related, but reversing the entire header does not establish any of them correctly. It can also reflect a logo or reverse a source order that was already suitable.

This guide uses a board-game lending catalogue with links to games, current reservations and collection points. The same catalogue appears as a horizontal navigation bar on a wide screen and a compact navigation panel on a narrow one. Its destinations and logical hierarchy remain stable while the presentation adapts to Arabic.

Give an Arabic document semantic RTL direction. A component embedded in an otherwise LTR page can declare its own boundary. Do not infer direction from an Arabic translation string or expect lang="ar" to change the layout by itself. MDN's dir reference explains these responsibilities.

Start with a meaningful link sequence. For the sample catalogue, the main destination precedes reservations, followed by collection points. These example URLs represent the catalogue's own routes:

html
<nav class="lending-nav" lang="ar" dir="rtl" aria-label="التنقل الرئيسي">  <ul class="lending-nav__links">    <li><a href="https://games.example/catalogue" aria-current="page">الألعاب</a></li>    <li><a href="https://games.example/reservations">حجوزاتي</a></li>    <li><a href="https://games.example/collection-points">نقاط الاستعارة</a></li>  </ul></nav>

Use the list to express the sequence and the navigation element to identify the region. MDN's nav reference describes that landmark. Give separate navigation regions names that distinguish their purpose, such as primary navigation and pagination, rather than assigning the same name to every group.

Changing locale does not automatically mean reversing the route array. If the sequence represents the same information hierarchy, preserve it and let the RTL layout express its reading direction. Change the information order only when the product has a reason to change that hierarchy or priority.

Keep source order meaningful before styling. That gives keyboard navigation, responsive layout and an unstyled page a coherent starting point instead of asking each presentation layer to compensate for a different sequence.

Remove the extra reversal from an RTL flex row#

For the same link list, this attempted RTL fix introduces another reversal:

css
/* Problem on the RTL navigation above. */.lending-nav__links {  display: flex;  flex-direction: row-reverse;}

An ordinary horizontal flex row already follows its container's direction. In RTL, its first source item starts at the right. row-reverse reverses that main axis again, placing the first item at the left. MDN's flex-direction reference documents both mappings.

For the intended Arabic sequence, replace that rule with:

css
.lending-nav__links {  display: flex;  flex-direction: row;  flex-wrap: wrap;  gap: 0.6rem 1.2rem;  margin: 0;  padding: 0;  list-style: none;} .lending-nav__links a {  display: block;  padding-block: 0.7rem;  padding-inline: 0.5rem;}

The first link now appears at the RTL row's start without changing the list's source order. In an LTR version, the ordinary row starts at the left. This is the component's intended directional behavior, not a separate set of link arrays.

The supplied layout measurements used Chromium 151 on September 24, 2026; Firefox and Safari were not measured. Test the order in your supported browsers, including wrapping and compact navigation, rather than checking only the first wide-screen row.

Do not generalize the correction to every reversed row in the product. A deliberately reversed presentation can have another purpose. Inspect the actual direction and intended sequence before removing or adding a reversal.

Verify focus order without inventing a second tab sequence#

In the sample navigation, Tab should encounter the games link, then reservations, then collection points. In the RTL row, that logical sequence proceeds from the right. Shift+Tab should traverse it in reverse.

Do not use positive tabindex values to repair a visual order created by CSS. That establishes another ordering mechanism that can diverge when links are added, hidden or moved into a compact layout. Correct the component's source and layout relationship instead.

W3C's Focus Order guidance requires an order that preserves meaning and operation. It does not require every possible interface to have one universal pixel-by-pixel traversal. A multirow header can have more than one reasonable design, but keyboard users must be able to understand and operate the sequence.

Test with real keyboard focus. Reading a source-order list or inspecting the accessibility tree does not establish where the focus indicator appears on screen. Conversely, a screenshot cannot show whether hidden links remain in the tab sequence.

Keep a visible focus indicator on each real link or button. A mirrored decorative highlight is not evidence that the interactive element itself has focus. Review focus near sticky headers and open panels so it does not disappear behind another navigation surface.

Provide a way to bypass repeated navigation, as W3C's Bypass Blocks guidance describes. If that mechanism is a skip link, translate its text and verify that it becomes visible on focus and reaches the intended content. Retest it after the compact header or route changes; bypassing the navigation should not land behind a sticky bar or at a target removed by the responsive layout.

Assign header alignment according to roles#

Decide which header elements belong at inline start and inline end. Primary navigation, brand identity, account actions and a locale switcher need an explicit grouping policy; they are not interchangeable items in one array to reverse.

Use logical spacing to express those relationships. For example, an auto margin at inline start can separate a trailing utility group from the preceding links in either interface direction. Check which element owns that margin and which direction it inherits. CSS logical properties for RTL covers those mappings in detail.

Keep the logo consistent with the brand's artwork rules. An Arabic brand asset may be a separate asset. Reflecting the English logo with a transform is not a substitute for that decision. The same caution applies to text, account avatars and icons that do not encode directional movement.

Do not let one intentionally LTR item turn the whole header LTR. A Latin product name or external service label can have its own content boundary while the surrounding navigation remains Arabic. For mixed labels, use Arabic and English mixed text in HTML rather than changing the header's direction to stabilize one token.

Inspect the rendered header after authentication and permission changes too. A longer account label or an additional destination can expose a spacing assumption that the logged-out screenshot did not exercise.

Preserve hierarchy in a vertical sidebar#

A vertical navigation list does not need its top-to-bottom sequence reversed for Arabic. Keep the catalogue's section order meaningful, align labels to the appropriate inline start and express nested indentation with logical spacing. A child collection should remain a child of the same parent after the presentation changes direction.

Do not turn a nested list of destination links into an ARIA tree just because the design uses indentation. If the sidebar simply reveals nested links, its disclosure and link behavior can remain simpler. A tree widget has a different interaction contract; choose it for the task it supports rather than as a visual styling label.

For collapsible sections, keep the parent destination and expansion action distinct when both exist. Check that closing one branch does not hide the currently focused link without moving focus to an appropriate visible control. On reopening, verify that the active destination and the expanded branch still agree with the current page.

Test indentation with a long Arabic child label. A physical margin copied from the English sidebar can put the hierarchy on the wrong side, while excessive indentation can remove the room needed to distinguish destinations. The fix should preserve both hierarchy and readable text.

Treat site dropdowns as navigation disclosures#

An ordinary set of links revealed by a button does not automatically need the ARIA menu or menubar interaction model. W3C's disclosure navigation example explains why typical site navigation can use disclosure buttons and links without menu roles.

Keep links as links and disclosure actions as buttons. If a primary item both has a destination and reveals child links, define those actions clearly. A single target that navigates on one device but only opens a panel on another creates an interaction ambiguity that RTL styling cannot solve.

The disclosure button's expanded state must agree with the visible child links, and its controlled-region reference must identify the correct panel. Support keyboard and touch activation instead of relying only on hover. Closing should not leave focus inside content that has become unavailable.

Translate the button's accessible name and any expanded-section instructions. A visible Arabic label can conceal an English aria-label added by the component library. Do not describe the action only as “left menu” or “right menu” when the component changes sides; name its destination or purpose.

Test the full open-close sequence from more than one primary item. Correcting the first popup can leave another with a different ancestor, offset or clipping boundary. If the library renders panels outside the header, inspect their actual DOM direction rather than assuming they inherit from the disclosure button.

Align dropdowns to the intended edge, then handle collisions#

For an inline-start-aligned popup beneath a positioned navigation item, this physical rule keeps choosing the left edge:

css
/* Problem for an Arabic item whose popup should start at its right edge. */.lending-nav__item {  position: relative;} .lending-nav__panel {  position: absolute;  top: 100%;  left: 0;}

For that same intended alignment, replace the panel rule with:

css
.lending-nav__panel {  position: absolute;  inset-block-start: 100%;  inset-inline-start: 0;}

MDN's inset-inline-start reference explains the direction-sensitive edge. In horizontal LTR layout, the intended left anchor is retained; in RTL, start becomes right. Remove the old physical offsets when applying the replacement.

This applies to a popup positioned inside that wrapper. A portalled or library-positioned popup can use a different containing block and a positioning engine's calculated coordinates. Configure its supported logical alignment instead of mechanically replacing generated left values with logical properties.

Alignment is not collision handling. Test panels wider than their trigger near both viewport edges, inside a sticky header and while the page scrolls. The correct fallback can shift the panel or place it above the trigger. Do not classify every such shift as an RTL defect before checking the intended fallback.

If clipping or overflow remains, use debugging RTL layout problems. Raising z-index does not by itself change the boundaries that clip the panel.

Preserve breadcrumb hierarchy and change its presentation#

A breadcrumb represents ancestry, not the sequence of pages visited. For a game-detail page, its logical trail can be catalogue, strategy games, then the current game. Keep that root-to-current sequence meaningful in the source.

In a horizontal RTL presentation, the root belongs at the right and the trail progresses toward the current item at the left. Do not reverse both the item array and the layout to obtain a particular screenshot. When the trail wraps, a doubly reversed implementation can reveal a different reading order.

The WAI-ARIA breadcrumb pattern describes a labelled navigation region and the current-page indication. Keep decorative separators out of the link names. A separator describes the hierarchy between items; it is not text users need repeated as part of every destination.

Use a separator appropriate to the displayed progression rather than assuming a hard-coded English chevron is correct. Check the actual icon asset and orientation. If the current game's title is Latin or mixed-script, isolate the title's content without changing the breadcrumb's overall hierarchy.

On narrow screens, preserve access to the parent destinations even if the design collapses part of a long trail. Do not shorten labels until distinct branches look identical. Test the full title and the fallback presentation, not just a short placeholder trail.

Give back, next and previous controls explicit meanings#

A back arrow can mean return to the catalogue, go to a parent collection or revisit browser history. Those are different actions. Name the actual destination when it is fixed, such as العودة إلى الألعاب, and use a link to that destination.

For a control that truly invokes browser history, account for entry from an external site or a direct link. Do not assume the previous history entry is the catalogue's Arabic parent page. The control's visual direction and its destination both need review.

For this catalogue's RTL sequential controls, the design defines progress toward inline end and return toward inline start. In its horizontal RTL sequence, the forward arrow points left and the return arrow points right. Choose arrows that represent those movements in that context. A CSS flip applied to every arrow can also change unrelated icons, while an icon library may already provide the mirrored variant.

Pagination adds a data sequence. Next must request the next result page under the active sort and filters, regardless of where its button appears. Reversing a visible list of page links does not change which data page is next. Check the URL or request after activation, then return and verify the same filter state remains.

Prefer action labels over physical instructions such as “click the left arrow.” The physical side can change between locales, screen sizes or layouts. Text naming the action remains useful through those changes.

Keep active destinations distinct from selected tabs#

The main navigation's current page can use aria-current="page", as the sample does for the games destination. Its visual indicator should remain associated with that link in both directions and after the row wraps.

Define current-page matching by route identity. A raw URL-prefix test can mark a parent and child link as the current page simultaneously, while a strict full-URL comparison can lose the indicator when only catalogue filters change. Decide which destination represents the page and distinguish that state from an expanded ancestor section. Recheck the indicator after back navigation and after a link is conditionally removed; it should not remain attached to an obsolete list position.

Do not convert ordinary destination links into tabs merely because the design draws an underline. The WAI-ARIA tabs pattern describes a widget that changes associated panels and has its own focus and selection behavior. Site links that navigate elsewhere retain their link behavior.

For an actual horizontal tab widget, verify arrow-key movement against its visual ordering in RTL. A handler that always increments a source index on Right Arrow may move focus toward the opposite physical side after layout direction changes. Use the component's documented direction support and test the actual focus target, not just the selected underline.

For ordinary navigation links, do not add that tab-widget keyboard model. Tab and Shift+Tab already provide native link traversal. Mixing two models can make the same visible bar behave differently depending on which item receives focus first.

Make compact navigation usable while closed and open#

At a narrow width, decide whether the catalogue uses an in-flow disclosure or a modal navigation panel. A side panel is not automatically a modal dialog just because it covers part of the page. The interaction model determines focus and background behavior.

An in-flow disclosure should reveal its links in a meaningful place in the normal sequence. A modal panel must provide the expected modal behavior, including managed focus, dismissal and unavailable background interaction. W3C's modal dialog pattern describes that model.

Hiding a panel by moving it off screen is not enough to make its links unavailable to keyboard users. Use the component's supported hidden or inert state where appropriate. MDN's inert reference explains its effect on interaction and focusability.

After dismissal, return focus to an appropriate visible control, normally the opener when the user has not navigated elsewhere. After following a link, handle the destination's normal focus behavior instead of trying to return focus to an obsolete opener.

Test changing width while the panel is open and while a nested section has focus. A compact-menu state that survives into the wide layout can leave duplicate links, hidden active content or focus on an element that no longer exists. Side placement, opening motion and focus availability are separate properties to verify.

Let Arabic labels determine the responsive layout#

Test the complete navigation wording and the actual Arabic font before choosing the collapse point. A breakpoint selected from shorter English labels can leave a cramped intermediate layout with clipped destinations and no visible compact-menu control.

Allow wrapping where the design supports it, or move to the compact presentation before links become unusable. Do not hide horizontal overflow to make the header appear contained while removing access to a destination. W3C's Reflow guidance explains why content and functionality need to survive smaller viewing areas.

If a navigation region deliberately scrolls, make its remaining content discoverable and reachable through keyboard focus. Verify the active destination can be brought into view. A narrow scroll strip with no visible sign of additional links can hide options despite technically retaining them in the DOM.

Check focus outlines, dropdown panels and account controls after text enlargement too. A header can fit its resting labels while clipping the focus indicator or covering the first line of page content when it becomes taller.

Verify language switching as navigation#

Switching the interface to Arabic should take the user to the corresponding destination when that destination exists. Replacing the header labels while leaving its links aimed at the English routes creates a translated navigation shell that immediately leads away from the selected language.

Build link destinations from the route and locale model, rather than deriving them from translated captions. The games destination can retain a stable identity even when its visible label and URL differ between languages. This also prevents a translation edit from accidentally changing current-page matching or navigation behavior.

Specify which search, sort and reservation context should survive a language change. Then test switching from a filtered catalogue and from a game-detail page, not only from the home page. If a destination is unavailable in Arabic, give it an intentional fallback rather than silently replacing every switch with a trip to the homepage.

After the switch, verify the document direction, navigation destinations, current-page indication and open-panel state together. A router can update the text while preserving stale component state. Close or reconcile any dropdown that no longer has the same destination or opener, and keep the resulting focus on a meaningful visible element.

Test navigation as a route through the interface#

Start at the catalogue, open a child section, visit a game detail, follow a breadcrumb parent and return through pagination or the current reservation link. Check destination, language, visible active state and focus after each action. This exposes more than a static header review.

StateWhat to verify
Wide RTL primary navigationSource sequence appears in the intended reading order
Tab and Shift+Tab through linksFocus preserves the logical sequence and remains visible
Open a dropdown near either edgeDirection, anchor and collision fallback are coherent
Breadcrumb with a long current titleHierarchy remains understandable after wrapping
Use back or next controlsArrow meaning agrees with the actual destination or data change
Open and close compact navigationHidden links are unavailable; dismissal leaves usable focus
Resize with a section openOne coherent navigation state remains
Enlarge Arabic textDestinations, focus indicators and controls remain reachable

Translate visible links and hidden navigation names together. Review after login, after a permission-dependent destination appears and with the longest supported labels. Inspect both source order and the actual focused element on screen; neither observation replaces the other.

A free Ritla scan can report R025: Directional icon pointing against the sequence its control advances, and R081: flex row-reverse faking RTL instead of dir (tab order fights visual order). For a remaining order problem, RTL flexbox helps trace direction and reversal before changing the navigation data.

Checks in this guide

See what your Arabic pages are hiding

Paste a URL. Ritla renders the page on desktop and mobile, runs every check, and shows the top issues with screenshot evidence.

Scan a page freeBrowse the checks