Segmentation de l'interface utilisateur Kibana en plusieurs composants, partie 1 : évolutivité de CSS

Le monde impitoyable de l'évolutivité de CSS

Des dizaines de milliers de lignes CSS, 8 niveaux de sélecteurs imbriqués, une succession de overrides jusqu'à ce que… (horreur, malheur !)… !important pointe le bout de son nez ! Certains développeurs peuvent trembler à la seule évocation de ces impitoyables lignes de code. Mais au sein de l'équipe Kibana, nous ne reculons pas devant de tels obstacles. Nous les affrontons à coup de tasses de café et d'inspecteurs Web.

Est-ce exagéré ? Peut-être un peu. Mais l'écriture d'un code CSS évolutif représente un défi réel. Dans l'équipe Kibana nous nous attaquons à ce problème en adoptant une approche formelle pour son écriture :

  • Nous considérons notre interface utilisateur comme une succession de plusieurs composants.
  • Nous utilisons des classes pour simplifier notre CSS.
  • Nous utilisons la syntaxe BEM pour rendre notre balisage et notre code CSS plus prévisible et plus lisible.

Nous créons notre interface utilisateur à partir de composants

Les composants sont les éléments constitutifs d'une interface utilisateur. Ils représentent les boutons, les champs de formulaire, les fenêtres modales et les autres éléments visuels que les développeurs assemblent lors de la création d'une fonctionnalité.

En écrivant le CSS sous forme de composants, nous facilitons la vie de nos développeurs, qui peuvent ainsi accéder au code CSS et au balisage existant au lieu d'avoir à tout écrire eux-mêmes.

Le code CSS écrit sous forme de composants est également plus facile à gérer, car un élément limite naturellement la portée de ses propres styles, et empêche ainsi tout effet indésirable lorsque nous modifions les styles.

Voici un exemple de composant, nous l'avons baptisé Panel :

Our Panel component

Les composants ont à la fois une représentation visuelle et une représentation dans le code, qui portent toutes deux le même nom. Ceci nous permet d'utiliser le même langage pour parler de l'interface utilisateur. Désormais, à chaque fois qu'un designer, un développeur ou un chef de produit fait référence à un composant « Panel », tout le monde sait exactement de quoi il s'agit.

Nous allons maintenant vous montrer comment nous procédons pour que notre CSS reste simple, puis nous jetterons un œil au code CSS qui se cache derrière notre composant Panel.

La simplicité est au cœur de l'évolutivité du CSS

Un code simple est plus stable et indique clairement son objectif. Les blocs de base qui le composent sont dissociées les unes des autres, ont des interactions explicites et sans ambiguïté, et ont des frontières bien définies.

Un code CSS simple possède ces mêmes qualités, mais les méthodes avec lesquelles nous le simplifions sont différentes de celles que nous utilisons pour simplifier un code écrit dans des langages impératifs tels que JavaScript ou Python. Au sein de l'équipe Kibana, nous considérons que l'outil le plus puissant dans notre trousse de simplicité reste la classe CSS.

Voici les règles générales décrivant la façon dont nous utilisons les classes pour simplifier notre CSS :

Utilisez des classes pour explicitement mapper le balisage au rendu de l'interface utilisateur. Lorsque nous nommons des classes en tenant compte des composants, les noms de classe deviennent porteurs de sens. Ces noms de classe font, en quelque sorte, office de points de repère et de panneaux de signalisation dans notre balisage. Ils nous aident à parcourir les balises, à comprendre les relations entre les éléments et à former une image mentale de l'interface utilisateur sans avoir à constamment ouvrir notre navigateur.

Limitez les sélecteurs à une seule classe. Lorsqu'un sélecteur comporte plus d'une classe, il devient dépendant du contexte. Cela signifie que ses styles dépendent d'une relation spécifique entre les éléments pour prendre effet, et cette relation peut être difficile à repérer par la simple lecture des balises. En limitant chaque sélecteur à une seule classe, nous simplifions les relations entre les éléments, ce qui rend notre balisage plus facile à lire et réduit toute probabilité d'accident lors de la modification du contexte.

Utilisez uniquement des propriétés héritées dans des nœuds terminaux. Lorsque du CSS applique des propriétés telles que « font-size » et « color » à un élément, il les applique également aux enfants de l'élément par héritage. Ces effets secondaires peuvent parfois être inattendus et sont souvent peu souhaitables. Notre solution consiste à empêcher l'héritage de décider de l'apparence de notre interface utilisateur en utilisant uniquement les propriétés héritées pour les parties de notre interface utilisateur qui ne contiennent pas d'enfants, par exemple les libellés des formulaires et les boutons.

Voyons comment ces principes s'appliquent au code de notre composant Panel. Voici le balisage destiné à créer un Panel :

<div class="panel">
  <div class="panelHeader">
    <div class="panelHeader__title">
      Panel title
    </div>
  </div>

  <div class="panelBody">
    <!-- Content goes here -->
  </div>
</div>

Remarquez comment l'interface utilisateur est clairement identifiée par l'utilisation de noms de classe dans le balisage. Nous voyons bien qu'il s'agit d'un composant Panel contenant un en-tête et un corps de texte. Au sein de l'équipe Kibana, nous avons constaté que l'amélioration de la lisibilité de notre balisage nous permet aussi de créer des interfaces utilisateur avec plus de rapidité et de fiabilité.

Voici le code CSS qui définit l'apparence de ce balisage :

.panel {
  border-left: 2px solid #e4e4e4;
  border-right: 2px solid #e4e4e4;
  border-bottom: 2px solid #e4e4e4;
}

.panelHeader {
  display: flex;
  align-items: center;
  padding: 10px;
  height: 50px;
  background-color: #e4e4e4;
}

  /*
   * FYI, we indent child classes like this to emphasize its role
   * in the markup as a tightly-coupled child of the .panel class.
   */
  .panelHeader__title {
    font-size: 18px;
    line-height: 1.5;
  }

.panelBody {
  padding: 10px;
}

Notez la façon dont nous avons déclaré chaque sélecteur à l'aide une classe unique. Ainsi, il est vraiment plus facile pour nous de comprendre l'influence du code CSS sur le balisage et la façon dont celui-ci crée un composant visuel dans l'interface utilisateur.

Enfin, notez que le seul sélecteur qui a des propriétés héritées est la classe .panelHeader__title car nous savons que l'élément auquel ce sélecteur sera appliqué ne contiendra jamais des enfants au-delà du texte du titre du composant Panel. Ceci est donc un exemple de la façon dont nous évitons les problèmes que le modèle d'héritage CSS peut engendrer.

La syntaxe BEM

La syntaxe BEM a considérablement gagné en popularité depuis qu'elle a été développée par Yandex en 2007. Expliquer les nuances de la BEM n'est pas l'objectif de cet article. Donc, si ce sujet vous intéresse, je vous recommande de lire cet article écrit par Harry Roberts ou cet article de CSS-Tricks pour en savoir plus.

Nous avons choisi la syntaxe BEM comme convention de nommage pour CSS car nous avions besoin d'un moyen d'identifier la cohésion entre les différentes classes qui constituent un composant lorsque nous lisons notre balisage. Nous avions également besoin d'une méthode pour différencier le rôle que chaque classe joue dans notre balisage – en effet, certaines classes ont un rôle structurel, d'autres modifient leur environnement, tandis que d'autres encore sont destinées à être appliquées dynamiquement via JavaScript. La syntaxe BEM nous fournit des modèles pour différencier toutes ces classes.

Pour en savoir plus sur le fonctionnement de la syntaxe BEM, ouvrez les liens mentionnés précédemment.

À venir : le processus de segmentation en composants

Ceci conclut donc la 1ère partie d'une longue série. Dans un prochain article, je vous parlerai de ce que nous avons appris sur le processus de segmentation en composants, y compris la méthode de conception des composants pour la réutilisation et la composabilité. Je vous remercie d'avoir pris le temps de lire mon article.

Si vous souhaitez rejoindre notre équipe, n'hésitez pas à nous contacter car nous sommes toujours à la recherche des meilleurs talents.