Arabic & RTL check library
Every check Ritla runs, and how to fix it
Every deterministic check Ritla runs on every page it scans, with what it looks for and how to fix what it finds. The same page produces the same findings every time.
41 checks
Document and metadata
Whether the page declares itself Arabic and right-to-left, and whether its title, metadata, canonical and alternates agree with that.
- document direction missing, contradicted, or declared only in CSSSet the document direction on the root element: <html dir="rtl" lang="ar"> (use your regional tag, e.g. ar-SA), and make sure no stylesheet overrides it.
- html[lang] missing, non-Arabic, or contradicting detected contentDeclare the content language on the root element: <html lang="ar">, prefer a regional tag like ar-SA or ar-AE when the product targets a specific market.
- hreflang alternate set lacks any Arabic entry on an Arabic pageAdd the Arabic self-reference to the alternate set: <link rel="alternate" hreflang="ar" href="…"> alongside the existing entries.
- <title> or meta description majority-Latin on an Arabic pageTranslate the <title> and meta[name=description], they are the page's face in search results and browser tabs.
- OpenGraph/Twitter metadata untranslated or og:locale missing/invalidTranslate og:title/og:description and set an Arabic locale: <meta property="og:locale" content="ar_SA">. ar_AR is valid, it is Facebook's generic Arabic, but a regional tag reads better to a regional audience.
- Canonical URL points at a different-locale variantPoint rel=canonical at the Arabic URL itself; cross-locale canonicals tell search engines the Arabic page is a duplicate of the foreign one.
Untranslated content
English left behind in an Arabic interface: body text, buttons, navigation, placeholders, alt text and labels.
- Visible Latin-script body text above thresholds on an Arabic pageTranslate the content. If a passage is intentionally foreign, mark it lang="…" (and translate="no" for names) so tools and screen readers treat it correctly.
- Untranslated interactive labels (buttons, nav/footer links, menu items, tabs)Translate interactive labels first, users navigate by them. Brand names can stay Latin (mark translate="no").
- Untranslated attribute text (placeholder, alt, title, aria-label, button value)Translate attribute strings too, placeholders guide input, alt text feeds screen readers and SEO.
Direction and bidi
Containers, alignment, inputs and icons that run the wrong way, and mixed Arabic and Latin text the bidi algorithm will reorder.
- Forced-LTR container, or a bidi override, over Arabic contentRemove the dir="ltr" (direction inherits from the page) or use dir="auto" for user-generated content of unknown language.
- Unisolated bidi hazards: phones, emails, Latin tokens inside Arabic textWrap direction-sensitive tokens: <bdi>…</bdi> or <span dir="ltr">…</span>. Phone numbers must stay LTR: <span dir="ltr">+966 55 123 4567</span>.
- text-align: left explicitly set on majority-Arabic textUse logical alignment: text-align: start (or remove the declaration, start is the default). Physical `left` pins Arabic text to the wrong edge.
- Text inputs rendered LTR where Arabic input is expectedSet dir="rtl" (or dir="auto") on free-text inputs and textareas. Keep email/tel/url inputs LTR.
- Punctuation rendering at the wrong visual end of Arabic textUsually a symptom of string concatenation across direction boundaries, isolate the embedded run (<bdi>/dir spans) instead of patching punctuation.
- Directional icon pointing against the sequence its control advancesMirror directional icons under RTL, [dir=rtl] .icon-arrow-right { transform: scaleX(-1) }, or swap the sprite for the opposite glyph. An arrow named for a physical side points the wrong way the moment the page flips.
Physical CSS
Left and right written into styles that should follow the reading direction: margins, floats, shadows and transforms.
- Direction-sensitive physical properties without an RTL overrideRewrite physical properties as logical ones: margin-left → margin-inline-start, padding-right → padding-inline-end, left → inset-inline-start, … One declaration then serves both directions.
- float: left/right on content elements in RTL context without overrideUse float: inline-start / inline-end (or flex/grid) so the float mirrors with direction.
- Direction-sensitive shadow x-offsets without an RTL counterpartMirror x-offsets under [dir="rtl"] (box-shadow: -10px …) or keep shadows symmetric.
- translateX moves the element off-screen in RTL
Layout
Horizontal overflow, overlapping text, clipped labels and fixed widths that Arabic text outgrows, at every breakpoint.
- Document-level horizontal overflowFind the widest element (see evidence), cap it with max-width: 100% and replace fixed pixel widths with fluid sizing. Test at 390px.
- Visible text-bearing elements overlappingUsually a physical offset that didn't mirror (negative margins, absolute positioning). Rework with logical properties and test in RTL.
- Clipped text: content wider than its box with overflow hidden and no ellipsisLet the container size to its content (remove the overflow trap), allow wrapping, or add text-overflow: ellipsis if truncation is intended.
- Fixed-pixel-width container whose Arabic text exceeds the spaceReplace the fixed width with max-width / min-inline-size: fit-content, Arabic strings are frequently wider than the English they were sized for.
Typography
Fonts without Arabic glyphs, letter-spacing that breaks joined letters, cramped line height, and Latin styling applied to Arabic.
- Arabic text falling back past the declared font family (measured, declared, or a webfont that failed to load)Declare an Arabic-capable face: font-family: "IBM Plex Sans Arabic", "Noto Sans Arabic", Tahoma, sans-serif, or subset with unicode-range so Arabic gets a deliberate face instead of the system default.
- letter-spacing applied to Arabic text (breaks the connected script)Reset tracking for Arabic: :lang(ar) { letter-spacing: 0 }. Arabic letters connect along a baseline - spacing them apart breaks the joins, and pulling them together overlaps the letterforms.
- line-height below 1.5 on Arabic body textGive Arabic body text line-height: 1.6–1.9. Ascenders, descenders, and diacritics need more vertical room than Latin metrics assume.
- Arabic body text below 14pxUse ≥ 15–16px for Arabic body text; Arabic glyphs carry more detail per em than Latin and turn to noise at small sizes.
- Italic/oblique applied to Arabic textArabic has no italic tradition, browsers synthesize an ugly mechanical slant. Emphasize with weight or color instead: :lang(ar) em { font-style: normal; font-weight: 600; }.
- Latin display styling (uppercase + tracking) applied to ArabicThis selector was styled for Latin display type (uppercase + letter-spacing). Give Arabic its own display treatment, the transforms are no-ops or harmful on Arabic.
Numbers, dates and currency
English dates, mixed digit systems, foreign currency formats, and punctuation in the wrong script.
- English month/day names or MM/DD/YYYY dates in Arabic textFormat dates with Intl.DateTimeFormat('ar-AE'), or 'ar-SA-u-ca-gregory-nu-latn' if you target KSA and want Gregorian dates with Western digits. Plain 'ar-SA' defaults to the Umm al-Qura calendar with Arabic-Indic numerals, deliberate if you want Hijri, a surprise if you do not.
- Arabic-Indic and Western digits mixed in the same contextPick one numeral policy per product and enforce it with Intl.NumberFormat('ar-SA', { numberingSystem: 'arab' }), or 'latn', everywhere.
- Foreign currency formatting in a SAR/AED market contextFormat prices with Intl.NumberFormat('ar-SA', { style: 'currency', currency: 'SAR' }), and keep one currency notation (ر.س vs SAR) across the page.
- Percent/unit ordering inconsistencies (%50 vs 50%)Type percentages digits-first (50% / ٥٠٪) and keep one convention; '%50' is a bidi-typing artifact, not a locale format.
- Latin punctuation, or wrong-script letterforms, inside Arabic textUse the Arabic marks in Arabic copy: ، for the comma, ؛ for the semicolon, ؟ for the question mark. They are separate characters, not styling, the Latin forms read as untranslated typography.
Forms
Inputs whose direction does not match what they hold, untranslated labels and validation, and missing autocomplete hints.
- tel/email/url inputs rendered RTL (these must stay LTR)Force LTR on machine-format fields: <input type="tel" dir="ltr">. Phone numbers, emails, and URLs are left-to-right strings even in Arabic UIs.
- Untranslated form labels / validation / help textTranslate every string a user needs to complete the form, labels, hints, and above all error messages; an unreadable error is a dead end.
- <select> rendered LTR with Arabic optionsLet the select inherit RTL (remove the direction override) or set dir="rtl" on it; LTR selects misalign the chevron and the option text.
- Identity fields missing autocomplete tokensAdd autocomplete tokens (name, email, tel, street-address…), they cost nothing and spare Arabic users retyping in fields that often fight their keyboard.
Accessibility
The language attributes screen readers depend on, and layouts where the tab order fights the visual order.
- Intentional foreign-language runs missing a lang attributeAdd lang to intentional foreign runs: <p lang="en" translate="no">…</p>, Arabic screen-reader voices mangle unmarked English.
- flex row-reverse faking RTL instead of dir (tab order fights visual order)Remove flex-direction: row-reverse and let dir="rtl" mirror the flexbox naturally, keyboard/tab order then matches what users see.
- UI text referencing physical arrow directionsPhrase directions logically ("التالي/السابق", next/previous) or flip the referenced key per direction, physical left/right instructions invert in RTL.
Run every check on your own page
Paste a URL. Ritla renders the page on desktop, tablet and mobile, runs every check, and shows the top issues with screenshot evidence.
Scan a page freeBrowse the checks