La localisation est l’un des domaines les plus intéressants en termes d’interface utilisateur : la longueur du texte peut être différente selon la langue, les alignements de texte par défaut peuvent varier, le sens de lecture peut être en miroir ou vertical, et bien d’autres cas différents. . Bref, c’est un incroyable source de diversitéce qui rend nos interfaces et notre travail frontal beaucoup plus solides, plus fiables et plus stimulants.
Le besoin d’interfaces de droite à gauche
La plupart des langues, comme le français ou l’anglais, sont conçues pour être lues de gauche à droite (LTR). Cependant, dans ces cas, certaines langues comme le farsi (persan), l’arabe et l’hébreu ont un sens de lecture différent : de droite à gauche (RTL).
La question est Quoi Pouvons-nous adapter nos interfaces à ce grand changement ?
Avant les propriétés CSS logiques
Avant CSS Logical Properties, nous pouvions faire des adaptations RTL avec différentes méthodes :
- Ajout d’un fichier CSS dédié uniquement pour le balisage/la mise en page RTL ;
- Recharger uniquement les parties qui doivent être adaptées dans le même CSS, par exemple
[dir="rtl"] .float-left { float: right; }
.
Même si ces méthodes fonctionnent (j’ai utilisé la seconde pour créer une version arabe du site Stand Up for Human Rights il y a quelques années), elles sont toutes les deux assez sous-optimales :
- Vous devez conserver un autre fichier pour le premier ;
- Le fichier CSS du second est un peu plus lourd et il peut y avoir quelques problèmes à régler (spécificité, plus de propriétés à ajouter, etc.).
Bien sûr, nous pouvons créer une grosse machine avec Sass pour produire plusieurs builds et utiliser des outils comme UnCSS pour supprimer ce qui n’est pas nécessaire, mais soyons honnêtes : c’est ennuyeux et peut conduire à des morceaux de code « non naturels »comme dans l’exemple précédent.
Pourquoi les propriétés logiques CSS sont parfaites/prometteuses
C’est là qu’intervient le module de propriétés logiques CSS. L’idée principale de ce module CSS est d’avoir un abstraction logique qui nous permet de produire un dessin qui s’adaptera en fonction du sens du texte et du mode d’écriture (propriétés comme writing-mode
, direction
Oui text-orientation
Soit dir
attribut en HTML). Cela nous donne des possibilités comme horizontal de droite à gauche ou de gauche à droite, RTL vertical, etc.
Mise en œuvre dans la pratique
Comment ça marche
Il y a quelques concepts à comprendre, déjà expliqués par Rachel Andrews ici dans « Understanding Logical Properties and Values »:
- Nous ne pensons plus en termes de
left
/right
maisstart
/end
(De même pourtop
/bottom
): - on ne dit plus
width
Soitheight
Mais plutôtinline
Ouiblock
– assez classique. (Vous avez probablement entendu parler du réglage par défautinline
Soitblock
éléments. ?)
cette idée de start
/end
pas nouveau. Vous l’utilisez probablement tous les jours avec des choses comme justify-content: start
.
Félicitations, vous savez, presque, tout ! ? Voyons quelques exemples pratiques.
exemples
Commençons par les bases:
propriété classique | propriété logique |
---|---|
width |
inline-size |
height |
block-size |
min-width |
min-inline-size |
min-height |
min-block-size |
max-width |
max-inline-size |
max-height |
max-block-size |
Les marges suivent la même logique :
propriété classique | propriété logique |
---|---|
margin-top |
margin-block-start |
margin-bottom |
margin-block-end |
margin-left |
margin-inline-start |
margin-right |
margin-inline-end |
de même pour padding
. Passons au positionnement :
propriété classique | propriété logique |
---|---|
top |
inset-block-start |
bottom |
inset-block-end |
left |
inset-inline-start |
right |
inset-inline-end |
Simple, non ? float
, text-align
Oui border
suivre le même chemin :
Propriété/Valeur classique | propriété logique |
---|---|
float: left; |
float: inline-start; |
float: right; |
float: inline-end; |
text-align: left; |
text-align: start; |
text-align: right; |
text-align: end; |
border-top |
border-block-start |
border-bottom |
border-block-end |
border-left |
border-inline-start |
border-right |
border-inline-end |
Je ne détaillerai pas d’autres comme resize
Soit scroll-margin-top
mais examinons plutôt le cas particulier de border-radius
:
propriété classique | propriété logique |
---|---|
border-top-left-radius |
border-start-start-radius |
border-top-right-radius |
border-start-end-radius |
border-bottom-left-radius |
border-end-start-radius |
border-bottom-right-radius |
border-end-end-radius |
Un peu différent, mais facilement compréhensible tout de même.
Certaines possibilités avec des valeurs sont vraiment cool – vous pouvez simplifier certaines notations. Voici quelques exemples supplémentaires :
Propriété/Valeur classique | propriété logique |
---|---|
margin-left: auto; margin-right: auto; |
margin-inline: auto; |
margin-top: 0; margin-bottom: 0; |
margin-block: 0; |
margin-top: 1em; margin-bottom: 2em; |
margin-block: 1em 2em; |
top: 0; left: 0; bottom: 0; right: 0; |
inset: 0; ? |
left: 10%; right: 10%; |
inset-inline: 10%; |
C’est de l’or pur dans le meilleur des mondes, n’est-ce pas ? Moins de code pour une prise en charge parfaite du langage RTL ! ?
Maintenant, je suis désolé d’ôter certaines des étoiles de vos yeux; en fait, il y a certaines limites.
certaines limites
syntaxe manquante
Les propriétés CSS logiques sont assez nouvelles, même si le support est bon dans les navigateurs récents. Cependant, le module CSS Logical Properties est un peu « jeune » et nécessite un niveau 2.
Pour donner un exemple simple : notre composant toggle utilise des transformations CSS entre différents états (chargement, actif, etc.), principalement parce que transform
c’est un moyen fiable d’avoir des transitions ou des animations fluides.
Donc, nous avons quelque chose comme ça :
.element {
transform: translateX(#{$toggle-width - $toggle-width-button});
}
Malheureusement, il n’y a pas de syntaxe relative au flux pour transform
. Donc, nous devons faire quelque chose comme ceci :
[dir="rtl"] .element {
transform: translateX(-#{$toggle-width - $toggle-width-button});
}
Si vous voulez avoir une idée des choses qui manquent comme celle-ci, vous pouvez vérifier les problèmes ouverts dans les accessoires CSS logiques.
Propriétés abrégées
Certaines notations abrégées ne sont actuellement pas prises en charge, telles que les valeurs 2, 3 ou 4 pour margin
:
Propriété/Valeur classique | propriété logique |
---|---|
margin: 1em 2em; |
margin-block: 1em; /* top and bottom */ margin-inline: 2em /* left and right */ |
margin: 1em 2em 3em; |
margin-block: 1em 3em; /* top, bottom */ margin-inline: 2em /* left, right */ |
margin: 1em 2em 3em 4em; |
margin-block: 1em 3em; /* top, bottom */ margin-inline: 4em 2em /* left, right */ |
N’utilisez pas ces exemples classiques avec des besoins logiques. Vous trouverez des problèmes car cela ne fonctionne pas réellement. Il vaut mieux être explicite. De plus, c’est plus lisible, à mon avis.
Montrant quelques vrais problèmes et quelques solutions
Images où le sens de lecture est important
Certaines images ont une signification directe. Prenons l’exemple des cartes à thème :

Dans ce cas, si nous appliquions simplement des éléments RTL à cela, nous obtiendrions ceci :

L’ordre est RTL, mais chaque image ne ressemble pas à une interface utilisateur RTL. C’est la version LTR ! Dans ce cas, c’est parce que le sens de lecture de l’image véhicule une information.

Nous avons un assistant de classe CSS qui facilite vraiment la réalisation de cette solution :
[dir="rtl"] .on-rtl-mirror {
transform: rotateY(180deg);
}
Cela s’applique également à toute image avec un sens de lecture, comme une flèche ou une icône à double chevron qui montre ou pointe vers quelque chose.
Styles/valeurs calculées via JavaScript
Disons que vous avez un plugin qui calcule un certain positionnement en JavaScript et fournit la valeur que vous pouvez utiliser en JS ou CSS. La bibliothèque déroulante que nous utilisons fournit uniquement les left
valeur dans les deux contextes RTL/LTR et transmettez-la à CSS à l’aide d’une propriété personnalisée CSS.
Donc, si nous utilisions cela avec des propriétés logiques, c’est-à-dire inset-inline-start: calc(var(--left) * 1px);
nous obtiendrions ce qui suit en cliquant sur le menu déroulant de l’utilisateur :

La solution est simple ici. On garde la propriété non logique :
/* stylelint-disable */
top: calc(var(--top) * 1px);
left: calc(var(--left) * 1px); // JS provide left value only
/* stylelint-enable */

Et nous avons désactivé notre peluche pour ce cas particulier.
Mélanger le contenu RTL et LTR
Même avec les meilleurs modules CSS, tous ceux qui ont fait du portage RTL vous diront que mélanger du contenu RTL et LTR donne parfois (souvent) des choses folles.
Prenons un exemple sur Proton Drive avec un composant appelé MiddleEllipsis
. Le but de ce composant est d’appliquer des points de suspension avant l’extension de fichier pour obtenir quelque chose comme my-filename-blahblahblah…blah.jpg
.
Rien de fou : nous divisons le contenu en deux parties et appliquons text-overflow: ellipsis
en premier. Vous pouvez vérifier la source de ceci MiddleEllipsis
composant.
Appliquons du vieux RTL ; alors nous devrions obtenir ceci :

Étrange, non ? C’est pourtant simple à expliquer :
MiddleEllipsis
la structure est RTL ;- Et nous injectons du contenu LTR. (Rappelez-vous, nous avons coupé ce contenu LTR avec RTL.)
Le navigateur fait du mieux qu’il peut, et ce qui s’affiche n’est pas mal de son point de vue, mais cela n’a pas de sens pour une personne. Dans ce cas, nous choisissons de conserver l’affichage LTR pour conserver le but des noms de fichiers, mais en l’alignant à droite :

Rechercher des modèles LTR natifs
Le MiddleEllipsis
L’exemple a montré que si UGC est LTR, il est préférable de l’afficher en tant que LTR.
Mais on peut se demander s’il y a des motifs qui sont naturellement LTR. La reponse courte est oui. Vous trouverez ci-dessous un exemple.
Numéro de téléphone
Le numéro de téléphone pourrait être le cas le plus évident ici, car il utilise généralement des numéros occidentaux, qui doivent être lus LTR.
Si on lui applique directement des accessoires logiques, cela pourrait donner ceci :

Bien que techniquement pas faux, c’est un peu bizarre à montrer +33 6 12 34 56 78
J’aime ça. Dans ce cas, nous avons décidé de conserver la gamme LTR par défaut pour éviter ce résultat étrange.

Nous avons le même cas pour une entrée 2FA utilisant des numéros occidentaux. Nous n’avons pas encore le cas, mais imaginez une entrée en 4 parties pour entrer une adresse IP. Cela n’aurait aucun sens de le montrer entièrement RTL comme les gens le comprendraient. 1.0.163.192
au lieu de 192.163.0.1
.
Compatibilité
Le plus gros problème auquel nous avons été confrontés concernait principalement la compatibilité. Cela peut être vu dans Puis-je utiliser des tables pour les supports logiques ?

Si la cible n’est que les navigateurs modernes récents, pas de problème. Mais si des versions plus anciennes de Safari sont nécessaires, par exemple, le support est assez mauvais. Et dans ce cas, les propriétés CSS logiques ne sont pas dégradées correctement. Par conséquent, tout peut sembler cassé.
Plusieurs options sont possibles :
- Il sert une version CSS pour les navigateurs modernes et une pour les navigateurs plus anciens ;
- Tout transpiler pour chaque cas.
Dans le cas de Proton, comme nous n’étions pas tout à fait prêts à livrer un langage RTL lorsque nous l’avons fusionné, et pour d’autres raisons, la décision a été prise de tout transpiler vers les bonnes vieilles propriétés CSS. Nous avons récemment trouvé une solution pour un cas qui nécessitait le support RTL pour la langue farsi (compte VPN) :
- Nous avons créé deux fichiers CSS : un moderne avec des accessoires logiques et un hérité ;
- Nous chargeons le moderne;
- Nous avons testé le support correct de
border-start-start-radius
; - S’il n’est pas pris en charge, nous revenons à l’héritage.
conclusion
Même si la perfection absolue est hors de ce monde, passer aux propriétés CSS logiques est un déménagement vraiment intéressant et un bon pari pour l’avenir: Nous écrivons moins de code avec ces plugins CSS logiques et réduisons la quantité de travail futur en les utilisant, donc ça va vraiment dans une direction passionnante.
En conclusion, et même si cela nécessitait plus de travail, nous avons testé un affichage RTL vertical pour tester des propriétés CSS plus logiques.

Cela semble assez intéressant, n’est-ce pas? ?
Ressources associées
- « Ressources W3C i18n », W3C.org
- « Style RTL 101 », Ahmad Shadeed
- « Quels langages utilisent les scripts RTL ? », Richard Ishida, W3C
- « Problèmes ouverts dans les pièces jointes logiques CSS », W3C, GitHub
- « Propriétés et valeurs logiques CSS », Docs Web MDN
- « Principes fondamentaux de l’algorithme bidirectionnel Unicode », Richard Ishida, W3C
- « Propriétés et valeurs logiques CSS de niveau 1 », ébauche de travail du W3C
- « Publication assistée par ordinateur multilingue : Trucs et astuces #3 », Kirill Fedotov, InText
- « Comprendre les valeurs et les propriétés logiques », Rachel Andrew

(Oui oui)