Letter-spacing: the error that disconnects Arabic letters

Arabic is a cursive script: every letter joins its neighbour according to its position in the word. The CSS letter-spacing property adds space after every character without knowing anything about those joins, so the result is a text cut into separate letters. The error shows up most often in headings, when styles designed for Latin text are copied onto the Arabic version as they are.

The fix is simple: set letter-spacing to normal or 0 on Arabic text, and use word-spacing if you want to open up a heading without breaking the joins. Keep letter-spacing for the Latin content on the page only. At Somu Raqami, removing this spacing from Arabic headings is a standard step in every project.

  • letter-spacing: normal or 0 on Arabic elements.
  • word-spacing to open up headings without breaking letter joins.
  • Keep positive letter-spacing values for Latin content only.

Mixed-content direction: why phone numbers and brand names flip

Any Arabic sentence containing a phone number, a Latin brand name, a link or an order reference needs an explicit direction. The Unicode bidirectional algorithm classifies every character, and digits read left to right even inside an Arabic context. Without proper isolation, the number or the brand name lands in the wrong place in the sentence.

The fix starts at the root: add dir=rtl and lang=ar to the html tag of every page. Inside the text, isolate every Latin run in an element with dir=ltr or in a bdi element, and use dir=auto for the fields the client types into. The W3C recommends logical properties such as margin-inline-start instead of fixed right/left values, and warns against relying on the CSS direction property alone: styles can be disabled or lost when content is copied.

  • dir=rtl on the html tag of every Arabic page, including error pages.
  • Isolate Latin runs with span dir=ltr or bdi.
  • dir=auto in input fields that receive client names.
  • Logical properties (inline-start/inline-end) instead of fixed right/left.

Font fallback layout shift: metrics and size-adjust in plain words

When an Arabic web font loads with font-display: swap, the browser first renders a fallback font and then swaps in the web font. If the two fonts' metrics differ — letter widths and heights — the text moves and the page jumps, which is most visible on phones, where these shifts are felt the most.

The fix has three simple parts: size-adjust is a zoom dial applied to the fallback font so its letters occupy the same space the web font will occupy; ascent-override, descent-override and line-gap-override pin the vertical metrics so the lines stay put no matter which font renders. At Somu Raqami we declare a metrics-matched fallback with a simple percentage adjustment, and we measure the result at a real phone width, never on a desktop screen.

  • Declare a local fallback font in @font-face instead of letting the system choose.
  • Set size-adjust to a percentage that matches the fallback to the web font.
  • Pin ascent, descent and line-gap with the metric override descriptors.
  • Measure the shift at a real phone width: desktop measurements hide these jumps.

Line-height: Arabic needs more room than Latin

Arabic carries diacritics above and below the letters, deep descenders and tall ascenders. A line-height inherited from Latin designs — around 1.2 or 1.4 — clips the diacritics or presses the lines together and makes reading hard work.

Use a unitless value such as 1.7 on long text: it scales with the font size in every context, and go higher for vocalised headings. Also check that overflow: hidden does not clip descenders or diacritics, and that service cards do not impose a fixed height on vocalised Arabic text.

  • A unitless line-height on Arabic text.
  • A higher value for vocalised and large headings.
  • Avoid fixed pixel heights in cards and buttons.

Mirrored icons and SVG text: what must flip and what must not

Icons that carry a directional meaning — next arrow, back, share, undo — must mirror their direction in an Arabic interface, otherwise they point the client the wrong way. Neutral icons like the clock, search or camera never mirror. Mirroring is not automatic: the Unicode algorithm mirrors punctuation characters, not icon drawings.

The practical fix: apply transform: scaleX(-1) to directional icons only inside the [dir=rtl] selector, or export two versions of the drawing. In an SVG, add direction=rtl to the svg tag, and to change direction inside a tspan element add unicode-bidi with the value embed, as the W3C documents in its SVG tutorial.

  • Mirror the directional: navigation arrows, back, share, undo.
  • Do not mirror the neutral: clock, search, camera, location.
  • scaleX(-1) under [dir=rtl] instead of editing icon files by hand.
  • direction=rtl in svg and unicode-bidi: embed in tspan for Arabic text inside drawings.

The pre-launch checklist for an Arabic site

This list sums up the whole article: review it before publishing any Arabic page, and at every new launch. Every item can be checked by eye, exactly as your client sees it.

  • The html tag carries lang=ar and dir=rtl on every page, including error pages.
  • No positive letter-spacing on any Arabic text.
  • Every phone number, Latin name or link inside an Arabic sentence is isolated with the correct direction.
  • The fallback font has matched metrics and the shift is measured at a real phone width.
  • Arabic line-height reaches at least 1.7 unitless and clips no diacritics.
  • Directional icons are mirrored under RTL and neutral icons are intact.
  • SVG texts carry direction=rtl.
  • Full test with the web font blocked to see the fallback state.