Skip to content
Thanawi

RTL & bidi

How to build layouts that work left-to-right and right-to-left from the same code, and handle mixed-direction text correctly.

Direction comes from the root

Direction and language are set once, on <html>. Components never hard-code a direction; they inherit it.

<html lang="ar" dir="rtl">

Both English and Arabic are first-class. Design and review every screen in both, not just the default. Every preview on this site has an EN / AR toggle that switches the example’s language and direction, so you can check both without leaving the page.

Logical properties only

Physical properties (left, right, margin-left…) describe the screen. Logical properties (inline-start, inline-end) describe the reading direction, so the layout mirrors itself. Physical properties are not allowed anywhere in the system.

Physical (don’t)Logical CSSTailwind
margin-leftmargin-inline-startms-*
margin-rightmargin-inline-endme-*
padding-left / -rightpadding-inline-start / -endps-* / pe-*
left: 0 / right: 0inset-inline-start / -endstart-0 / end-0
text-align: lefttext-align: starttext-start
border-leftborder-inline-startborder-s
border-top-left-radiusborder-start-start-radiusrounded-ss-*, rounded-s-*
float: leftfloat: inline-startfloat-start

Toggle the preview below between EN and AR. The markup is identical; only dir and lang on the container change, and the layout, alignment and directional icons follow:

Transfer from Al RajhiToday, 10:42+ SAR 12,500.00

Icons

Icons that point along the reading direction flip in RTL; vertical, symmetric and real-world icons don’t. Flip with rtl:-scale-x-100 on the icon. The full list is on Icons › RTL flipping.

FlipDon’t flip
Horizontal and diagonal arrows, left/right chevronsVertical arrows and chevrons, download, upload
Send, reply, forward, undo / redoSymmetric glyphs: plus, ×, check, info, alerts
Trending up / down, log in / out, external linkSpinner, refresh, clock (rotation, not direction)
Move left / rightReal-world objects (search, document) and brand marks
<ChevronRight className="size-4 rtl:-scale-x-100" />

Numbers, currency and identifiers

Numbers, IBANs, phone numbers, emails and code are left-to-right even inside Arabic text. Isolate them, so the surrounding punctuation doesn’t jump to the wrong side:

  • Wrap inline runs in <bdi>, or give them dir="ltr". Both isolate the run.
  • Inline code on this site is isolated with unicode-bidi: isolate automatically.
  • Inputs for Latin-only data (email, IBAN, phone) get dir="ltr", so the caret and the text move in the expected direction.
<p>
  سيتم تحويل <bdi>SAR 12,500.00</bdi> إلى الحساب <bdi dir="ltr">SA03 8000 0000 6080 1016 7519</bdi>
</p>

<input type="email" dir="ltr" autoComplete="email" />

Review checklist

  • The screen is reviewed in both dir="ltr" and dir="rtl".
  • No physical properties or utilities (left, right, pl-, mr-, text-left …).
  • Directional icons flip; object icons don’t.
  • Amounts, IBANs and phone numbers are isolated and read correctly.
  • Truncation and wrapping work in both languages. The Arabic and English versions of a label can differ a lot in length.