Skip to content
RTL & Arabic Web

Why component libraries break in RTL, and what to check first

The recurring failures in component libraries, design systems and utility CSS when direction changes — and the one refactor that removes most of them.

Why do component libraries break in RTL?

Mostafa Nouh — portraitMostafa NouhPublished 7 min read

1. Physical properties

A component written with margin-left, padding-right, left: 0 and text-align: left works perfectly until direction changes, at which point every one of those values points the wrong way. The logical equivalents — margin-inline-start, padding-inline-end, inset-inline-start, text-align: start — mirror automatically and require no second stylesheet.

2. Transforms and signed offsets

translateX(-50%) does not mirror. Neither does a carousel that advances by subtracting pixels, nor a drawer that slides in from translateX(100%), nor an arrow that nudges +4px on hover. CSS has no logical transform, so these have to be handled per direction — and the failure is silent, because the code still runs and the element still moves, just toward the wrong edge.

3. Icons that carry direction

  • Mirror these: back and forward arrows, next and previous, indentation, undo and redo, reply, trending lines, progress chevrons.
  • Never mirror these: a clock, a play button, a checkmark, a logo, a magnifier, anything with Latin text inside it.
  • A blanket transform: scaleX(-1) on every icon in RTL will flip your brand mark and your play button. It happens constantly.

4. Mixed content and bidirectional text

A phone number, a price, a version string, a date or a Latin product name inside an Arabic sentence will be reordered by the bidirectional algorithm unless the run is isolated. The result is not a styling flaw — a date rendered as 13-09-2026 when it should read 2026-09-13 is a wrong fact on the page, and a machine reading it records the wrong fact.

html
<!-- reorders: the + jumps, the groups swap -->
<p>اتصل على +20 150 515 5999</p>

<!-- holds: the Latin run is isolated -->
<p>اتصل على <span dir="ltr">+20 150 515 5999</span></p>
One attribute, and the number stops being wrong.

5. Typography settings that do not apply

Arabic is a joined script. letter-spacing pulls the connections apart and produces text that reads as damaged — so a design system applying a global tracking value to headings must neutralise it in RTL. The same applies to text-transform: uppercase, which does nothing in Arabic, and to font weights, because Arabic at the same numeric weight as Latin always reads heavier.

The first pass on any RTL bug report

  • Search the stylesheet for left, right, margin-left, padding-right and text-align: left.
  • Search for translateX, scrollLeft and any signed pixel offset in JavaScript.
  • Check every animation's keyframes, not its direction property.
  • List every icon and decide, one by one, whether it carries direction.
  • Wrap every Latin or numeric run inside Arabic text in dir="ltr".
  • Neutralise letter-spacing and uppercase under [dir="rtl"].
  • Confirm the scrollbar gutter — in RTL it sits on the inline-start edge and changes your width maths.

Sources

Contact

Have a site or store that needs to work better?

Tell me what is happening and on which page. A diagnosis is a useful first deliverable on its own.

I read every message myself and reply within one working day — usually with a question or two before anything else, because a scope worth quoting needs them answered.

Available for remote work aligned to EST hours
Mostafa Nouh — portrait

Mostafa Nouh

Full-Stack Developer & Product Builder

Location
Egypt · Remote