One interface. Three languages. One stylesheet.
Kurdish and Arabic read right to left. English does not. Most
“RTL support” is direction: rtl
and a hope — which gets the boxes roughly right and everything
inside them subtly wrong. Press a language and watch what moves, and more
importantly what deliberately does not.
Shipments this week
The layout CSS, in full
/* what most people write — needs a whole second stylesheet */ margin-left: 1rem; border-left: 3px solid; text-align: left; padding-right: .8rem; /* what this page writes — mirrors itself, no overrides */ margin-inline-start: 1rem; border-inline-start: 3px solid; text-align: start; padding-inline-end: .8rem;
There is no [dir="rtl"] layout rule anywhere in this
sample’s stylesheet. The mirror is a property of the writing
mode, not a second design.
What flips, and what must not
- ✓Layout, padding, borders. Automatic, because they are written logically.
- ✓The “onwards” chevron. It means a direction, so it mirrors.
- ✓The progress bar. It fills from the start edge — the right-hand side in Kurdish.
- ✗The logo. A mark is a picture of itself. Mirroring it produces a different logo.
- ✗Numbers and money. Digits run left to right in every one of these languages.
- ✗The reference code.
RF-2291is isolated, or bidi moves the hyphen. - ✗A clock or a play button. Time does not run backwards because the text does.
How it is designed
I build for a market where Kurdish, Arabic and English all turn up in the same product, often on the same screen. That is a specific skill, and it is almost never shown in a portfolio — so here it is, working.
direction: rtl is about five per cent of the job
It gets the boxes roughly right and leaves everything inside them subtly wrong. The other ninety-five per cent is writing the layout in logical properties in the first place, then deciding, one by one, which things are directional and which are objects.
Write it logically once, rather than mirroring it twice
margin-inline-start instead of margin-left,
border-inline-end instead of border-right,
text-align: start instead of left. The panel
above is one set of rules producing both directions. The alternative
— a base stylesheet plus an RTL override file — means every
future change has to be made twice, and the second one gets forgotten.
Not everything should mirror, and the list is short
The logo does not: a mark is a picture of itself, and flipping it makes a different mark. Media controls do not, because play still means forwards. Clocks do not. But the chevron that means onwards does, and the progress bar fills from the right in Kurdish. Getting the bar backwards is the single most common tell that a site was translated rather than designed.
Numbers are the part that quietly breaks
Digits run left to right in all three of these languages, so a price or a
reference dropped into an RTL sentence has to be isolated — with
<bdi> or unicode-bidi: isolate — or
the bidi algorithm reorders the surrounding punctuation and
RF-2291 comes out as something else entirely.
Kurdish has no Intl data, and it fails silently
This one caught me while building the page, which is why it is here.
Ask any current browser for ckb-IQ and you do not get an
error — you get en-US. A fully Kurdish screen then
renders Aug 29 and Latin digits, and nothing anywhere reports a
problem until a user does.
supportedLocalesOf is the only way to find out, and it has
to be asked rather than assumed. This page asks, and falls back to
ar-IQ — same script, same region, same digit
conventions, which is a far better wrong answer than English. Switch to
Kurdish and the header says so out loud rather than hiding it.
Digits are a product decision, not a technical one
ar-IQ resolves to the arab numbering system, so
Intl returns Eastern Arabic-Indic digits by default. Whether
that is what a particular audience wants is a question for the client,
not for the library — plenty of Iraqi software uses Western digits
throughout. Either can be forced with a locale extension
(ar-IQ-u-nu-latn), and the header above prints both so the
difference is visible rather than argued about.
The font stack has to cover the script
A Latin-only stack falls back to whatever the system has, and Kurdish renders in a substitute face with the wrong metrics and broken joining. That single omission is why so much bilingual work looks unfinished even when the layout is correct.