MSSamara Stack

Home › Articles

How to build a proper Arabic (RTL) website

Moath Samara · Published October 18, 2026

I recently posted a command inside an Arabic sentence on X, and part of it displayed wrongly: the slash in /bye moved after the word, so it read “bye/”. The problem is not the platform alone. It hits any site that mixes Arabic and English without care. This guide shows how to build an Arabic site properly from the start.

1. Start with lang and dir

The first line of your page sets language and direction. Browsers, screen readers and search engines depend on it:

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

Set the direction with the dir attribute in HTML, not in CSS alone, because it is part of the meaning of the page. The attribute also isolates the text inside the element from the text around it.

2. Logical properties instead of left and right

If you write margin-left, you must rewrite everything when the direction flips. Logical properties follow the page direction automatically, so you write the rule once. According to MDN, margin-inline-start equals margin-left on left-to-right pages and margin-right on right-to-left pages.

Physical propertyLogical equivalent
margin-left / margin-rightmargin-inline-start / margin-inline-end
padding-left / padding-rightpadding-inline-start / padding-inline-end
border-leftborder-inline-start
text-align: lefttext-align: start
float: leftfloat: inline-start
left: 0inset-inline-start: 0
width / heightinline-size / block-size

A common trap: writing margin: 0 after a logical property resets it. Use the logical shorthands consistently, or put the logical property last. Flexbox and Grid already follow the direction, so setting direction: rtl flips the order of items with no extra work.

.card {
  margin-inline-start: 1rem;
  padding-inline: 1rem 2rem;   /* start end */
  text-align: start;
  border-inline-start: 4px solid var(--accent);
}

In modern Tailwind you get the equivalents ms-4, me-4, ps-4, pe-4 and border-s-2. Check your version's docs for the exact names.

3. Mixed text: the source of most bugs

When you put an English part (a command, a link, a product name) inside an Arabic sentence, the Unicode algorithm tries to guess the direction of punctuation and symbols, and it can guess wrong. Example: اكتب /bye للخروج.

The fix is to isolate the English part. According to the W3C: if you know the direction, add the dir attribute. If you do not (text from a database or a user), use dir="auto" or the <bdi> element.

<p>Arabic text <bdi dir="ltr">ollama run gemma4:e2b</bdi> more Arabic text.</p>

<!-- user-generated text, direction unknown -->
<p>Name: <bdi>{userName}</bdi></p>

Do not rely on unicode-bidi: isolate in CSS alone for meaning. MDN notes that CSS may be ignored, while the <bdi> element carries the meaning.

Where you cannot use HTML: in social posts and plain text, put the English part on its own line. To keep it inside the sentence, surround it with the characters U+2066 (LRI) and U+2069 (PDI), which isolate left-to-right text.

Always left-to-right: email addresses, links, phone numbers and terminal commands. Give them dir="ltr".

4. Icons and images

[dir="rtl"] .icon-arrow { transform: scaleX(-1); }

5. Fonts and spacing

6. Numbers and dates

Number habits differ across Arab countries: some prefer Arabic-Indic digits and some Western digits. Let the user or their country decide, and format with Intl, no libraries needed:

new Intl.NumberFormat('ar-EG').format(1234.5)
new Intl.NumberFormat('ar-EG-u-nu-latn').format(1234.5)
new Intl.DateTimeFormat('ar-SA-u-ca-islamic-umalqura').format(new Date())

The first gives Arabic-Indic digits, the second forces Western digits, and the third gives a Hijri (Umm al-Qura) date. Test what you see before you publish.

7. Forms and inputs

<!-- free text: direction follows what the user types -->
<input type="text" dir="auto">

<!-- always left-to-right -->
<input type="email" dir="ltr">
<input type="tel" dir="ltr">

Common mistakes and fixes

SymptomCauseFix
An element sticks to the wrong sideA fixed margin-left or leftLogical properties (inline-start / inline-end)
Punctuation jumps somewhere oddLatin text inside an Arabic sentence with no isolationbdi, a dir attribute, or a separate line
Arabic letters look separatedletter-spacing on Arabic textRemove letter-spacing
A phone number or link is reversedDirection not setdir="ltr" on the element
An arrow points the wrong wayA directional icon was not mirroredscaleX(-1) inside [dir="rtl"]
Bold text looks distortedFake bold for a font with no bold weightLoad the real font weight

Pre-launch checklist

  1. Toggle dir on the html element between rtl and ltr in the developer tools, and confirm the whole layout flips.
  2. Test this sentence in your pages: اكتب /bye ثم Ctrl+C (أو Enter) للخروج.
  3. Put in a long link and a long English name, and watch for horizontal overflow.
  4. Open the page on a real phone, not just the emulator.
  5. Check that directional icons flipped and logos did not.

FAQ

Do I need a separate CSS file for Arabic?

No, if you use logical properties. You write the rules once and they work in both directions.

Is direction: rtl in CSS enough?

It works, but setting dir in HTML is better because it is part of the content's meaning, which is what the W3C recommends.

Can I just translate the interface and mirror it?

No. Test real Arabic text, numbers and dates, and the font. Automatic mirroring is not enough.

A new tool every day

I post a free AI tool on X every day, and all sources and paths live in the library.

Follow on X   Open the library

Sources