Sur un projet qui grossit, les feuilles de style CSS commencent presque toujours par ressembler à un jardin bien rangé, puis finissent en jungle : des classes génériques comme .title, .button ou .item se marchent dessus, une correction sur une page casse silencieusement une autre, et personne n'ose plus toucher au CSS sans tout retester. BEM est né pour éviter précisément ce scénario.
Ce n'est ni un framework, ni une syntaxe CSS particulière : c'est une convention de nommage de classes, pensée pour que le nom d'une classe raconte à lui seul la structure du composant qu'elle habille.
Définition
BEM signifie Block, Element, Modifier (bloc, élément, modificateur en français). C'est une méthodologie de nommage des classes CSS, popularisée par l'équipe de Yandex, qui organise chaque nom de classe autour de trois notions : le bloc, composant autonome et réutilisable ; l'élément, une partie du bloc qui n'a pas de sens hors de lui ; et le modificateur, une variante d'apparence ou d'état du bloc ou de l'élément.
/* Bloc */
.card {
}
/* Élément : appartient au bloc .card */
.card__title {
}
.card__image {
}
/* Modificateur : variante du bloc */
.card--highlighted {
}
/* Modificateur : variante d'un élément */
.card__title--large {
}La syntaxe utilise deux underscores pour relier un bloc à son élément (card__title) et deux tirets pour relier un bloc ou un élément à son modificateur (card--highlighted). Cette régularité n'est pas un détail esthétique : c'est elle qui rend le nom d'une classe lisible sans avoir besoin d'ouvrir le HTML pour comprendre à quoi elle sert.
Le problème que BEM résout
Sans convention, un projet CSS de taille moyenne accumule rapidement deux maladies classiques. La première est la collision de noms : deux développeurs créent chacun une classe .title pour des besoins différents, et la seconde définition écrase silencieusement la première selon les règles de la Cascade. La seconde maladie est l'escalade de Spécificité : pour corriger un style qui ne s'applique pas comme prévu, quelqu'un ajoute un sélecteur plus précis, ou pire, un !important, ce qui rend la prochaine correction encore plus difficile.
BEM attaque les deux problèmes à la racine. Comme chaque classe BEM est un nom unique et explicite plutôt qu'un Sélecteur de classe générique combiné à des descendants, la spécificité reste plate : une seule classe suffit presque toujours, sans imbrication de sélecteurs. Et comme le nom du bloc préfixe systématiquement ses éléments, deux composants différents ne peuvent quasiment jamais entrer en collision, même sur un projet de plusieurs centaines de fichiers CSS.
Un exemple concret
Prenons un composant de recherche assez classique : un champ de saisie, un bouton, et une variante compacte utilisée dans l'en-tête du site.
.search-form {
display: flex;
gap: 8px;
}
.search-form__input {
flex: 1;
padding: 8px;
}
.search-form__button {
padding: 8px 16px;
}
.search-form--compact {
gap: 4px;
}
.search-form--compact .search-form__input {
padding: 4px;
}Le HTML correspondant se lit presque comme une phrase, sans avoir besoin de consulter la feuille de style pour comprendre la hiérarchie :
<form class="search-form search-form--compact">
<input class="search-form__input" />
<button class="search-form__button">Rechercher</button>
</form>Un nouveau développeur qui arrive sur ce projet comprend en un coup d'œil que .search-form__input appartient forcément au bloc .search-form, et que la variante compacte modifie l'espacement sans dupliquer les règles de base.
Où placer la limite entre bloc et élément
La difficulté principale de BEM n'est pas sa syntaxe, qui reste mécanique une fois apprise, mais le découpage : faut il créer un nouveau bloc ou simplement un élément de plus ? La règle la plus fiable consiste à se demander si ce fragment de HTML aurait un sens copié ailleurs dans le projet, isolé de son contexte d'origine. Si oui, c'est probablement un bloc à part entière. Si ce fragment n'existe et ne se comprend que collé à son parent, comme une icône à l'intérieur d'un bouton précis, c'est un élément.
| Situation | Choix recommandé |
|---|---|
| Une carte produit réutilisée sur plusieurs pages | Bloc (.product-card) |
| Le titre à l'intérieur de cette carte | Élément (.product-card__title) |
| Une variante grisée de la carte quand le stock est épuisé | Modificateur (.product-card--out-of-stock) |
| Un bouton générique utilisé dans dix contextes différents | Bloc indépendant (.button), pas un élément de chaque parent |
BEM face aux autres approches
BEM n'est pas la seule réponse au problème des collisions de classes. Les modules CSS, les solutions CSS-in-JS ou encore l'Imbrication CSS native native récemment arrivée dans les navigateurs offrent d'autres façons de circonscrire la portée d'un style. La différence, c'est que BEM ne demande aucun outil de build : c'est une pure discipline d'écriture, applicable dans n'importe quel projet, même le plus modeste, sans préprocesseur ni compilateur.
Cette absence de dépendance explique pourquoi BEM reste largement utilisé plus de dix ans après sa popularisation, y compris sur des projets qui utilisent par ailleurs des outils plus récents. Notre formation HTML et CSS reprend cette méthode dès les premiers projets pratiques, pour prendre l'habitude de structurer les classes avant qu'un projet ne grossisse.
Pièges courants
.card__header__title. BEM ne prévoit qu'un seul niveau d'élément par bloc. Si un élément a lui même une sous-structure complexe, la bonne pratique consiste soit à le traiter comme un bloc indépendant, soit à garder un nom plat comme .card__title, sans empiler les doubles underscores.Un second piège consiste à multiplier les modificateurs au point de recréer, sous une autre forme, la même explosion de classes que BEM cherche à éviter. Si un bloc accumule dix modificateurs différents qui se combinent entre eux, il vaut souvent mieux repenser le découpage en plusieurs blocs plus simples plutôt que de continuer à empiler les variantes.
FAQ
Non, BEM fonctionne aussi bien en CSS pur qu'avec un préprocesseur. Sass rend simplement l'écriture des classes imbriquées plus rapide grâce à l'esperluette &, mais la convention elle même ne dépend d'aucun outil et existait avant la généralisation des préprocesseurs dans les projets web.
Oui, sans aucun problème. BEM régit uniquement le nommage des classes, pas les propriétés CSS qu'on leur applique. Un bloc BEM peut très bien être un conteneur en display: flex ou en display: grid, la méthodologie de nommage et la technique de mise en page répondent à deux questions totalement différentes.
Un peu, au premier abord, mais cette contrainte se rentabilise rapidement. Des noms de classes plus longs mais explicites, comme .search-form__button plutôt que .btn, évitent des heures de recherche dans un inspecteur de navigateur pour comprendre à quel composant appartient réellement un style, surtout sur un projet repris par une autre personne plusieurs mois plus tard.