Que fait Arabic RTL Web ?
Une checklist pour les pages arabes qui se lisent naturellement, se mettent en page correctement à 375px et ne mélangent jamais les nombres, les URLs ou les mots anglais. Appliquez chaque section qui concerne la tâche, puis exécutez la checklist finale.
1. Direction et langue
- Élément racine :
<html lang="ar" dir="rtl">, écrit dans le HTML (pas ajouté par JavaScript) afin que le premier affichage soit déjà RTL. - Ne remplacez pas
dirpar CSSdirection: rtl. L'attribut pilote également le bidi, les contrôles de formulaire et les lecteurs d'écran. - Un bloc anglais dans une page arabe :
<p lang="en" dir="ltr">. Texte saisi par les utilisateurs (noms, commentaires, chat) :dir="auto".
2. Mise en page avec propriétés logiques
Les propriétés physiques left/right ne s'inversent jamais. Utilisez des propriétés logiques afin qu'une seule feuille de style fonctionne dans les deux directions.
| À éviter | À utiliser |
|---|---|
margin-left, padding-right | margin-inline-start, padding-inline-end |
left: 0, right: 0 | inset-inline-start: 0, inset-inline-end: 0 |
text-align: left | text-align: start |
border-left | border-inline-start |
border-top-left-radius | border-start-start-radius |
float: left | float: inline-start |
- Flexbox et grid suivent déjà
dir: en RTL,flex-direction: rowcommence à droite. N'ajoutez jamaisrow-reversepour "corriger" le RTL. transform: translateX(),background-positionet les décalages de box-shadow sont physiques. Inversez-les avec:dir(rtl)ou[dir="rtl"]si nécessaire.- Tailwind :
ms-*,me-*,ps-*,pe-*,start-*,end-*,text-start, et les variantesrtl:/ltr:.
3. Polices web arabes
- Choisissez une famille conçue pour l'arabe (IBM Plex Sans Arabic, Noto Naskh Arabic, Noto Sans Arabic, Tajawal, Cairo, Almarai, Readex Pro). Réservez les polices décoratives comme Aref Ruqaa aux titres uniquement.
- Auto-hébergez les fichiers WOFF2 : pas de requêtes tierces, fonctionne hors ligne, rien ne fuit vers un CDN de polices. Vérifiez la licence (OFL permet l'auto-hébergement).
- Utilisez
font-display: swapet séparez les fichiers arabes et latins avecunicode-range, afin que chaque page télécharge uniquement ce qu'elle utilise :
@font-face { font-family: 'Plex'; font-weight: 400; font-display: swap;
src: url(plex-400-ar.woff2) format('woff2');
unicode-range: U+0600-06FF, U+0750-077F, U+08A0-08FF, U+200C-200E, U+FB50-FDFF, U+FE70-FEFC; }
@font-face { font-family: 'Plex'; font-weight: 400; font-display: swap;
src: url(plex-400-lat.woff2) format('woff2');
unicode-range: U+0000-00FF, U+2000-206F; }
body { font: 400 17px/1.75 'Plex', 'Segoe UI', Tahoma, sans-serif; }
- L'arabe nécessite une hauteur de ligne plus élevée (1.6 à 1.8) pour les diacritiques et les jambages descendants, ainsi qu'une taille légèrement supérieure à celle du texte latin.
- N'utilisez jamais
letter-spacingsur l'arabe (cela brise la liaison des lettres). Pas detext-transform, pas d'italique artificiel. Éviteztext-align: justifysur les colonnes étroites. - N'étirez pas les mots avec tatweel (U+0640). Cela brise la recherche et le copier-coller.
4. Bidi : nombres, URLs et anglais dans l'arabe
L'algorithme bidi Unicode réordonne les caractères neutres à côté des nombres et du texte latin. Deux bugs classiques dans un paragraphe RTL :
- Téléphone
+966 55 123 4567affiche ses groupes de chiffres en ordre inverse :4567 123 55 +966. - Plage horaire
10:00 - 12:00s'affiche comme12:00 - 10:00.
Correctifs :
<bdi>autour des valeurs insérées de direction inconnue :مرحبًا <bdi>${userName}</bdi>، أهلًا بك.dir="ltr"sur les valeurs qui sont toujours LTR :<span dir="ltr">+966 55 123 4567</span>, URLs, emails, chemins de fichiers, IBANs,<code dir="ltr">,<pre dir="ltr">.- CSS pour les motifs répétés :
.num, .code { unicode-bidi: isolate; }. Notez que<bdi>isole par défaut. - Champs de saisie pour email, URL et téléphone :
<input type="email" dir="ltr">. - Là où le balisage est impossible (titre de document, notifications, chaînes simples), enveloppez avec des isolateurs Unicode : FSI U+2068 ... PDI U+2069, ou LRI U+2066 ... PDI pour un texte connu LTR.
5. Chiffres : un seul système par page
- Choisissez les chiffres latins
0-9ou arabo-indiens٠-٩(U+0660 à U+0669) et utilisez-les partout sur la page, y compris les tableaux, graphiques et dates. - Le mélange confond les lecteurs (un tableau avec les deux ressemble à une erreur), brise la recherche ("15" ne correspond pas à "١٥"), le tri et le copier-coller dans des tableurs.
- Les chiffres persans
۰-۹(U+06F0 à U+06F9) sont des points de code différents. Ne les mélangez pas. - Les valeurs par défaut d'
Intldiffèrent selon la locale et la version du moteur : dans Node 24,ar-SAformate avec des chiffres arabo-indiens tandis quearsimple donne des chiffres latins. Définissez le système de numération explicitement :new Intl.NumberFormat('ar-SA-u-nu-latn')ou'ar-SA-u-nu-arab'. - Avec les chiffres arabo-indiens, le séparateur décimal est
٫(U+066B) et le séparateur de milliers est٬(U+066C). - Piège réel : un point médian (U+00B7) utilisé comme séparateur à côté de chiffres arabo-indiens ressemble au zéro arabo-indien (U+0660), qui est aussi un petit point. "12, séparateur, 3" se lit alors comme "1203". Séparez plutôt avec la virgule arabe «،», une barre oblique, ou un espacement supplémentaire (CSS
gap).
6. Ponctuation arabe
- Utilisez
،(U+060C),؛(U+061B) et؟(U+061F), pas,;?. Le point et!sont partagés. - Pas d'espace avant un signe de ponctuation, un espace après : «كيف حالك؟» pas «كيف حالك ؟».
- Choisissez un style de guillemets («...» ou "...") par page.
7. Icônes et miroirs
Miroir des icônes qui montrent une direction ou une séquence : flèches arrière et suivante, chevrons dans les listes et le fil d'Ariane, steppers et direction de progression, "envoyer", indentation de texte et icônes de liste.
Ne pas mettre en miroir : logos et marques, contrôles média (lecture, rembobinage, avance rapide), horloges et minuteries, coches, photos, et icônes contenant des lettres ou chiffres latins.
:dir(rtl) .icon-dir { transform: scaleX(-1); } /* classe opt-in, jamais globale */
8. Saisie de nombres depuis des claviers arabes
- Préférez
<input inputmode="decimal" autocomplete="off">àtype="number". La valeur d'un champ number n'est valide qu'avec des chiffres ASCII, donc les chiffres arabo-indiens peuvent revenir comme une chaîne vide ; il ajoute aussi des boutons d'incrémentation. - Les utilisateurs tapent
٠-٩, le séparateur décimal arabe٫, et parfois des chiffres persans. Normalisez avantNumber():
function parseArabicNumber(raw) {
const s = String(raw ?? '').trim()
.replace(/[٠-٩]/g, (d) => d.charCodeAt(0) - 0x0660)
.replace(/[۰-۹]/g, (d) => d.charCodeAt(0) - 0x06F0)
.replace(/٫/g, '.')
.replace(/٬/g, '');
if (s === '') return null; // Number('') vaut 0, donc vérifier d'abord la chaîne vide
const n = Number(s);
return Number.isFinite(n) ? n : NaN;
}
parseArabicNumber('٩٥٫٥'); // 95.5
- Décidez comment une
,tapée est traitée (marque décimale ou séparateur de milliers) et documentez-le. - Affichez les messages de validation en arabe, définissez
aria-invalid, et liez le message avecaria-describedby. - Triez les noms arabes avec
new Intl.Collator('ar').compare. Pour la recherche, normalisez les formes d'alef (أ إ آ en ا), supprimez tashkeel et tatweel à la fois sur la requête et les données.
9. Tests
- Testez à 375px de large (et 320px si possible). Confirmez que
document.documentElement.scrollWidth <= innerWidth. - Testez les longs mots arabes avec lettres attachées, comme «والمستشفيات» ou «باستخداماتها», dans les titres et boutons. Utilisez
overflow-wrap: anywheresur les titres et cartes, etmin-width: 0sur les enfants flex et grid. - Utilisez du contenu arabe réel avec de l'anglais et des nombres mélangés, pas du lorem ipsum.
- Vérifiez sur Safari iOS et Chrome Android, ainsi qu'à 200% de zoom et l'ordre de focus au clavier (Tab se déplace de droite à gauche).
10. Le piège [hidden]
L'attribut hidden n'est qu'un display: none de l'agent utilisateur. Toute règle d'auteur telle que .card { display: flex } le surcharge, donc el.hidden = true cesse silencieusement de fonctionner. Ajoutez ceci à la feuille de style de base :
[hidden] { display: none !important; }
Checklist finale
-
<html lang="ar" dir="rtl">dans la source - Aucune propriété physique left/right restante dans le nouveau CSS
- Police arabe auto-hébergée,
font-display: swap, séparationunicode-range - Numéros de téléphone, URLs, code et noms d'utilisateur isolés
- Un seul système de chiffres ; pas de point médian à côté des chiffres arabo-indiens
- Ponctuation arabe, pas d'espace avant
- Seules les icônes directionnelles sont mises en miroir
- Les champs number acceptent
٠-٩et٫ - Pas de défilement horizontal à 375px ; les mots longs se coupent
-
[hidden] { display: none !important; }présent