Pour de plus étendus, interrelated éléments d'interface utilisateur requiérant un nombre de classes, on utilise des conventions de nommage BEM-like.
BEM, signifiant Block, Element, Modifier, est une méthodologie front-end mise au point par des développeurs travaillant à Yandex. Alors que BEM est une méthodologie complète, nous nous intéressons ici seulement à ses conventions de nommages. Et au-delà de cela, les conventions de nommages ici sont uniquement BEM-like; les principes sont exactement les même, mais la syntaxes diffère légèrement.
BEM divise les composants en trois groupes :
Pour faire une analogie (notez, ce n'est pas un exemple):
.person { } .person__head { } .person--tall { }
Les éléments sont délimitées avec 2 underscores (__), et les modifieurs sont délimités par deux tirets (–).
On peut voir ici que .person {} est le bloc, il s'agit de la racine d'une entité distinct. .person__head {} est un élément; c'est une plus petite partie du bloc .person {}. Enfin, .person–tall {} est un Modifier; c'est une variante spécifique du bloc .person {}.
Votre contexte de bloc démarre à l'endroit le plus logique, self-contained, distinct. Pour continuer avec notre analogie basée sur la personne, nous ne devrions pas avoir de classe comme .room__person {}, étant donné que la pièce (room) est un autre contexte bien plus élevé. Nous aurons sans doute des blocs séparés tels que :
.room { } .room[[__]]door { } .room--kitchen { } .person { } .person[[__]]head { }
Si nous voulons dénoter une .person {} à l'intérieur d'un .room {}, il est plus correct d'utiliser un sélecteur comme .room .person {} qui fait le pont entre deux blocs, que d'étendre la portée des blocs et éléments existants
Un exemple plus réaliste de blocs correctement scopés pourrait ressembler à ceci où chaque morceau de code représente son propre bloc.
.page { } .content { } .sub-content { } .footer { } .footer__copyright { }
Une notation incorrecte serait :
.page { } .page__content { } .page__sub-content { } .page__footer { } .page__copyright { }
Il est important de savoir quand le scope BEM commence et termine. Comme règle, BEM s'applique aux éléments distincts et self-contained de l'UI.
Si nous devions ajouter un autre élément — appelé, disons, .person__eye {}— à ce composant .person {} , nous n'aurions pas besoin de parcourir chaque niveau du DOM. c'est facile à dire, mais la notation serait .person__eye {}, et non .person__head__eye {}. Vos classes ne reflètent pas l'entièreté du DOM.
Vous pouvez avoir des variantes d'éléments, et ceci peut être dénoté de nombreuses manières différentes selon comment et pourquoi il sont modifiés. Pour continuer avec notre exemple de la personne, un œil bleu pourrait ressembler à ceci :
.person__eye--blue { }
Ici nous pouvons voir que nous modifions directement l'élément eye.
Les choses peuvent toutefois devenir plus complexes. excusez l'analogie quelque peu crue, mais imaginons avoir un élément face qui soit 'beau'. La personne elle-même n'est pas si belle, alors modifions l'élément face directement — un beau visage sur une personne habituelle :
.person__face--handsome { }
Mais si la personne est belle, et que nous voulons en modifier le visage à cause de cela ? Un visage normal sur une belle personne :
.person--handsome .person__face { }
Voici une des rares occasions où nous utilisons un sélecteur descendant to modify an Element based on a Modifier on the Block.
Si l'on utilise SASS, il est probable que nous l'écrivions ainsi :
.person { } .person__face { .person--handsome & { } } .person--handsome { }
Notez que nous ne nichons pas la nouvelle instance de .person__face {} dans .person–handsome {}; à la place, nous faisons usage du sélecteur de parent SASS pour prépend .person–handsome sur le sélecteur .person__face {} existant. cela signifie que toutes les règles related à .person__face {} existent à un seul endroit, et ne s'étalent pas dans tout le fichier. C'est une bonne pratique général lorsque l'on a affaire à du code niché : garder tout votre contexte (ici tout le code de .person__face {}) encapsulé en un unique endroit.