Méthodologie BEM

Par Xavier SENENTE

§ 1

Le problème des CSS

Inconvénients des CSS

  • Plus le sélecteur a de niveaux, plus il faut de temps pour atteindre l'élément et pouvoir appliquer le style.
  • Plus le sélecteur a de niveaux, plus il est difficile à déboguer.
  • Plus la spécificité du sélecteur est élevée, plus il est difficile à écraser et à déboguer.

Inconvénients des CSS

.this-one-class {
  color: #ccc;
}

Facile à lire et à maintenir

.grandfather.is-deaf .grandfather .son .grandchild {
  color: #ccc;
}

Difficile à lire et à maintenir

Spécificité

.grandfather .grandchild {
  color: #ccc;
}

Plus léger, plus facile à déboguer, plus facile à maintenir

#section {
  color: #ccc;
}

Spécificité élevé, difficile à surcharger

§ 2

BEM à la rescousse

Organisation des numéros de chambre d'hotel

3

Étage

15

15e chambre

315

N° chambre

B.

Block

E.

Element

M.

Modifier

Qu'est-ce que BEM ?

  • Une convention de nommage CSS développée par l'équipe de Yandex pour améliorer l'évolutivité et la maintenabilité du développement Web.
  • Un moyen de découper l'interface utilisateur en blocs indépendants.
  • Un moyen de structurer vos classes.

Avantages & inconvénients

Avantages

  • Développement rapide
  • Évolutivité
  • Approche sécuritaire
  • Réutilisation du code
  • Architecture stable
  • Sélecteurs très rapides

Inconvénients

  • Oblige à donner une classe à tous les éléments
  • Plus grande taille de fichier CSS

BEM — Block

  • Comparable à un composant d'interface
  • Logique indépendante et fonctionnelle
  • Peut être facilement réutilisé à d'autres endroits

Exemple: .navigation, .footer, .carousel

BEM block

BEM — Block

Les blocs peuvent être imbriqués dans n'importe quel autre bloc !

BEM block

BEM — Element

  • Une partie constitutive (enfant ou descendant) d'un bloc qui ne peut pas être utilisée en dehors de celui-ci.
  • Les éléments font sens dans le contexte d'un bloc.

Exemple: .nav__list, .nav__item, .nav__link

BEM element

BEM — Modificateur

  • Une variation d'apparence ou de comportement pour un bloc ou un élément.
BEM modifier

BEM — Composant

BEM component BEM component

Convention de nommage

En BEM, toutes les classes CSS sans exception commencent nécessairement par le nom du bloc.

  • Pour le bloc menu par exemple : .menu.
  • Pour les items du menu : .menu__item
  • Pour un item modifié du menu : .menu__item--selected

Convention de nommage

Lorsque vous nommez un bloc, concentrez-vous sur la description de son objectif (c'est-à-dire ce que c'est) plutôt que son apparence (c'est-à-dire à quoi il ressemble).

.btn

.nav

Correct

Dit ce que c'est

.big

.bright-pink

Incorrect

Dit à quoi ça ressemble

Exemple de composant simple pour un bouton

<a class="btn">
 <span class="btn__icon">…</span>
 <span class="btn__text">…</span>
</a>

Les erreurs à éviter !

<article class="card">
  <img src="..."/>
  <h3>...</h3>
  <p>...</p>
  <a>...</a>
</article>
.card {...}
.card img {...}
.card h2 {...}
.card p {...}
.card a {...}

Incorrect

Utilser les sélecteurs de type n'est pas recommandé en BEM.

<article class="card">
  <img class="card__img" src="..."/>
  <h3 class="card__title">...</h3>
  <p class="card__excerpt">...</p>
  <a class="card__link">...</a>
</article>
.card {...}
.card__img {...}
.card__title {...}
.card__excerpt {...}
.card__link {...}

Correct

Chaque élément a une classe qui lui est propre. On n'utilise plus les sélecteurs de type.

Exemple d'un bloc d'entrée

Exemple d'un bloc d'entrée

 html
<article class="card">
  <div class="card__img">…</div>
  <h3 class="card__title">
    <a class="card__title-link" href="">…</a>
  </h3>
  <div class="card__caption">
    <p class="card__date">…</p>
    <p class="card__excerpt">…</p>
    <a class="card__link" href="">…</a>
  </div>
</article>
 css
.card {...}
.card__img {...}
.card__title {...}
.card__title-link {...}
.card__caption {...}
.card__date {...}
.card__excerpt {...}
.card__link {...}

Les erreurs à éviter !

.block .block__element {
  ...
}
 
 
 

Incorrect

À ne pas faire

.block {
  ...
}
.block__element {
  ...
}

Correct

À faire

Les erreurs à éviter !

<div class="human">
 <div class="human__arm human__arm--left">
   <div class="human__arm__hand">
     <div class="human__arm__hand__finger"></div>
   </div>
 </div>
</div>

Incorrect

Plusieurs niveaux d'éléments par bloc

<div class="human">
 <div class="human__arm human__arm--left">
   <div class="human__hand">
     <div class="human__finger"></div>
   </div>
 </div>
</div>

Correct

Un seul niveau d'élément par bloc

Les erreurs à éviter !

<ul class="menu">
 <li class="menu__item">…</li>
 <li class="menu__item">…</li>
 <li class="menu__item--selected">…</li>
</ul>

Incorrect

Tous les éléments ne sont pas identifiés de la même manière

<ul class="menu">
 <li class="menu__item">…</li>
 <li class="menu__item">…</li>
 <li class="menu__item menu__item--selected">…</li>
</ul>

Correct

Tous les éléments sont identifiés et certains ont un modificateur en plus

Exemple de blocs imbriqués

 header
<header class="header">
  <div class="header__start">
    <img class="header__logo" src="..."/>
  </div>
  <div class="header__end">
    <ul class="header__menu">
      ...
    </ul>
    <button class="header__search">...</button>
  </div>
</header>
 menu
<ul class="header__menu menu">
  <li class="menu__item">
    <a class="menu__link" href="...">...</a>
  </li>
  <li class="menu__item">
    <a class="menu__link" href="...">...</a>
  </li>
  ...
  <li class="menu__item menu__item--dark">
    <a class="menu__link" href="...">...</a>
  </li>
</ul>