Fermer

décembre 23, 2022

Déploiement des propriétés logiques CSS sur les applications Web

Déploiement des propriétés logiques CSS sur les applications Web


Vous avez peut-être déjà entendu parler des propriétés logiques CSS ou des adaptations RTL, mais vous êtes encore en train de décider de les déployer à grande échelle. Pour vous aider à prendre conscience de leurs possibilités, Nicolas Hoffmann partage son expérience sur la façon dont lui et son équipe chez Proton ont effectué un passage massif des accessoires logiques CSS à la production et comment vous pouvez les considérer sous un angle différent dans vos propres projets.

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 par défaut du texte peuvent varier, le sens de lecture peut être inversé 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 destinées à ê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 comment pouvons-nous adapter nos interfaces à ce grand changement ?

Avant les propriétés logiques CSS

Avant CSS Logical Properties, nous pouvions faire des adaptations RTL avec différentes méthodes :

  • Ajout d’un fichier CSS dédié uniquement pour la surcharge/mise en page RTL ;
  • Surcharger 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 font le travail – j’ai utilisé la seconde pour créer une version arabe du site Stand Up for Human rights il y a quelques années – les deux sont assez sous-optimaux :

  • Vous devez conserver un autre fichier pour le premier ;
  • Le fichier CSS pour le second est un peu plus lourd, et il peut y avoir quelques problèmes à gérer (spécificité, plus de propriétés à ajouter, etc.).

Bien sûr, nous pouvons créer d’énormes machines avec Sass pour produire plusieurs versions et utiliser des outils comme UnCSS pour supprimer ce qui n’est pas nécessaire, mais soyons honnêtes : c’est ennuyeux et cela peut conduire à des morceaux de code « non naturels »comme dans l’exemple précédent.

Pourquoi les propriétés logiques CSS sont un ajustement parfait/prometteur

C’est là que le Propriétés logiques CSS module entre dans le jeu. L’idée principale de ce module CSS est d’avoir un abstraction logique qui nous permet de produire une mise en page qui s’adaptera en fonction de la direction du texte et du mode d’écriture (propriétés comme writing-mode, directionet text-orientationou alors dir attribut en HTML). Cela nous donne des possibilités comme le RTL horizontal de droite à gauche ou de gauche à droite, vertical, etc.

Mise en œuvre en pratique

Comment ça fonctionne

Il y a quelques notions à comprendre, déjà expliquées par Rachel Andrews ici dans «Comprendre les propriétés et les valeurs logiques” :

  • Nous ne pensons plus en termes de left/right mais start/end (Il en va de même top/bottom):
  • On ne dit plus width ou alors height mais plutôt inline et block — assez classique. (Vous avez probablement entendu parler de défaut inline ou alors block éléments. 😉)

Cette idée de start/end n’est pas nouveau. Vous l’utilisez probablement tous les jours avec des choses comme justify-content: start.

Félicitations, vous savez maintenant — presque — tout ! 🎉 Voyons quelques exemples pratiques.

Exemples

Commençons par les bases:

Propriété classiquePropriété logique
widthinline-size
heightblock-size
min-widthmin-inline-size
min-heightmin-block-size
max-widthmax-inline-size
max-heightmax-block-size

Les marges suivent la même logique :

Propriété classiquePropriété logique
margin-topmargin-block-start
margin-bottommargin-block-end
margin-leftmargin-inline-start
margin-rightmargin-inline-end

Il en va de même padding. Passons au positionnement :

Propriété classiquePropriété logique
topinset-block-start
bottominset-block-end
leftinset-inline-start
rightinset-inline-end

Simple, n’est-ce pas ? float, text-alignet border suivre le même chemin :

Propriété/valeur classiqueProprié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-topborder-block-start
border-bottomborder-block-end
border-leftborder-inline-start
border-rightborder-inline-end

Je ne détaillerai pas d’autres comme resize ou alors scroll-margin-topmais examinons plutôt le cas particulier de border-radius:

Propriété classiquePropriété logique
border-top-left-radiusborder-start-start-radius
border-top-right-radiusborder-start-end-radius
border-bottom-left-radiusborder-end-start-radius
border-bottom-right-radiusborder-end-end-radius

Un peu différent, mais facilement compréhensible quand même.

Certaines possibilités avec des valeurs sont vraiment cool — vous pouvez simplifier certaines notations. Voici quelques exemples supplémentaires :

Propriété/valeur classiqueProprié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 un support parfait des langages RTL ! 🎉

Maintenant, je suis désolé d’effacer certaines des étoiles dans vos yeux – il y a en effet certaines limites.

Plus après saut! Continuez à lire ci-dessous ↓

Certaines limites

Syntaxe manquante

Les propriétés logiques CSS sont assez nouvelles, même si le support est bon sur les navigateurs récents. Cependant, le module CSS Logical Properties est un peu « jeune » et a besoin d’un niveau 2.

Pour donner un exemple simple : notre composant bascule utilise des transformations CSS entre différents états (chargement, actif, etc.), principalement parce que transform 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 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 éléments manquants comme celui-ci, vous pouvez vérifier problèmes ouverts sur les props logiques CSS.

Propriétés abrégées

Certaines notations abrégées ne sont pas prises en charge pour le moment, comme les valeurs 2, 3 ou 4 pour margin:

Propriété/valeur classiqueProprié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 rencontrerez des problèmes car cela ne fonctionne pas. 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 :

Thèmes de protons dans LTR
Thèmes de protons dans LTR (Grand aperçu)

Dans ce cas, si nous appliquions simplement des trucs RTL à cela, nous obtiendrions ceci :

Thèmes de protons en RTL, mal faits
Thèmes Proton en RTL, mal faits. (Grand aperçu)

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

Thèmes de protons en RTL
(Grand aperçu)

Nous avons un assistant de classe CSS qui rend très simple la réalisation de ce correctif :

[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 montrant ou pointant vers quelque chose.

Styles/Valeurs calculés via JavaScript

Imaginons que vous ayez 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 ne fournit que les left valeur dans les deux contextes RTL/LTR, et nous transférons au CSS à l’aide d’une propriété CSS personnalisée.

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 liste déroulante de l'utilisateur est ouverte sur le côté opposé de l'interface, pas près de son bouton d'ouverture
(Grand aperçu)

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 */
La liste déroulante des utilisateurs est ouverte près de son bouton d'ouverture
(Grand aperçu)

Et nous désactivons notre peluche pour ce cas particulier.

Mélanger le contenu RTL et LTR

Même avec les meilleurs modules CSS, quiconque a déjà fait quelques adaptations RTL dira que mélanger du contenu RTL et LTR donne parfois (souvent) des trucs dingues.

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 du 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 sur le premier. Tu peux vérifier la source de ce MiddleEllipsis composant.

Appliquons du bon vieux RTL — nous devrions alors obtenir ce qui suit :

Affichage des fichiers dans Proton Drive, mieux affiché
(Grand aperçu)

Étrange, non ? C’est pourtant simple à expliquer :

  • MiddleEllipsis la structure est RTL ;
  • Et nous injectons du contenu LTR. (Rappelez-vous, nous avons coupé RTL ce contenu LTR.)

Le navigateur fait de son mieux, et ce qui est affiché n’est pas faux de son point de vue, mais cela n’a aucun sens pour une personne. Dans ce cas, nous avons choisi de garder l’affichage LTR pour garder le but des noms de fichiers mais en l’alignant à droite :

Affichage des fichiers dans Proton Drive, mieux affiché
(Grand aperçu)

Recherche de modèles LTR natifs

Le MiddleEllipsis exemple a montré que si le contenu généré par l’utilisateur 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 sont censés être lus LTR.

Si nous lui appliquons directement des accessoires logiques, cela pourrait donner ce qui suit :

Entrée téléphonique affichée en RTL, affichage bizarre
(Grand aperçu)

Bien que techniquement ce ne soit pas faux, c’est un peu bizarre d’afficher +33 6 12 34 56 78 comme ça. Dans ce cas, nous avons décidé de conserver l’alignement LTR par défaut pour éviter ce résultat étrange.

Entrée téléphonique affichée en LTR
(Grand aperçu)

Nous avons le même cas pour une entrée 2FA utilisant des nombres occidentaux. Nous n’avons pas encore le cas mais imaginez une entrée en 4 parties pour saisir une adresse IP. Cela n’aurait pas de sens de l’afficher entièrement RTL comme les gens comprendraient 1.0.163.192 à la place de 192.163.0.1.

Compatibilité

Le plus gros problème auquel nous avons été confrontés concernait principalement la compatibilité. Cela se voit sur Puis-je utiliser des tableaux pour les props logiques:

Puis-je utiliser des tableaux pour les props logiques
Puis-je utiliser des tableaux pour les props logiques (Grand aperçu)

Si la cible n’est que les navigateurs modernes récents, il n’y a pas de problème. Mais s’il y a un besoin pour les anciennes versions de Safari, par exemple, le support est assez mauvais. Et dans ce cas, les propriétés logiques CSS ne sont pas dégradées avec élégance. Ainsi, tout peut sembler cassé.

Plusieurs options sont possibles :

  • Servir une version CSS pour les navigateurs modernes et une autre pour les plus anciens ;
  • Tout transpiler pour chaque cas.

Dans le cas de Proton, comme nous n’étions pas totalement 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 de bonnes vieilles propriétés CSS classiques. Récemment, nous avons trouvé une solution pour un cas qui nécessitait la prise en charge de RTL pour la langue farsi (compte VPN) :

  1. Nous construisons deux fichiers CSS : un moderne avec des accessoires logiques et un hérité ;
  2. Nous chargeons le moderne;
  3. Nous testons le support correct de border-start-start-radius;
  4. 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 logiques CSS est un déménagement vraiment intéressant et un bon pari pour l’avenir: nous écrivons moins de code avec ces props logiques CSS, et nous réduisons la quantité de travail futur en les utilisant, donc ça va vraiment dans une direction passionnante.

Comme dernier point à retenir, et même si cela nécessiterait plus de travail, nous avons fait quelques tests d’un affichage RTL vertical pour tester d’autres propriétés logiques CSS.

Affichage vertical de droite à gauche, en mode écriture
(Grand aperçu)

Cela semble assez intéressant, n’est-ce pas? 😉

Éditorial fracassant
(yk, il)




Source link

décembre 23, 2022