Le 8 octobre 2026
BEM X classes utilitaires : lisibilité ou performance ?
Adieu la lourdeur de Bootstrap, aujourd'hui la grande mode est à TailwindCSS. Les classes utilitaires nous facilitent la vie. Prêtes à l'emploi, elles nous font gagner du temps et la taille de nos fichiers CSS est fortement réduite. Mais doit-on pour autant mettre de côté les autres méthodologies ?

L'approche utility-first
Les classes utilitaires comme celles de TailwindCSS permettent d'être ajoutées directement dans le HTML. Ce sont de petites classes type "flex", "text-center", "bg-blue-500" qui correspondent, en général, à une seule propriété CSS. Elles permettent aussi de gérer le responsive grâce à des classes comme "md:block". Il suffit d'un paramétrage de base pour qu'elles puissent être prêtes à l'emploi n'importe où dans le site.
Ces classes apportent un vrai gain de temps puisqu'il n'y a pas de règles à déclarer dans un fichier CSS. Il faut cependant bien les connaître pour ne pas perdre son temps dans la doc !
L'autre gain de TailwindCSS est la performance, puisque seules les classes présentes dans le HTML sont générées.
Mais il y a un mais : c'est moche !
On se retrouve avec du code du même acabit que le style inline et ça donne ça :
<a class="shrink-0 cursor-pointer rounded-[1.2rem] px-8 py-[1.4rem] text-left font-roboto text-[1.6rem] font-medium leading-8 transition-colors duration-200 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-fg-primary md:w-full md:shrink lg:px-[2.4rem] lg:py-[1.8rem] lg:text-[1.8rem] bg-green text-green-800 hover:bg-green-300" href="my-link">You found the label!</a>
Ce que je pourrais aussi reprocher à l'approche utility-first c'est un problème de scalabilité. Lorsque l'on veut réutiliser le même style pour un autre élément, il faut recopier tout ça et penser à le mettre à jour. On pourrait se dire que ce n'est pas vraiment un problème si on développe en React et qu'un composant CSS = un composant React, mais est-ce toujours le cas ?
La méthodologie BEM
Le BEM (Block Element Modifier) est une méthodologie de nommage qui permet d'éviter la duplication de code en pensant blocs isolés et réutilisables.
Le bloc parent a sa classe "card".
Les éléments enfants ont leurs classes "card__title", "card__img".
On ajoute des classes modifier pour les variations "card__title_center".
<div class="card">
<h2 class="card__title card__title_center">Ha, on y voit plus clair !</h2>
<img class="card__img" src="" />
</div>
Cette façon de faire permet aussi d'éviter les batailles de spécificité que l'on aurait pu avoir si on avait écrit "card h2". Avec le BEM, le !important n'a pas lieu d'être ! Quel que soit son contexte, le composant garde ses styles intacts.
Mais voilà, ça fait beaucoup de classes dont il faut définir les règles, et parfois le nombre de variations peut être élevé à cause des différentes possibilités de positionnement dans la page.
BEM X classes utilitaires
Au fil des années et avant même l'arrivée de TailwindCSS, je suis finalement arrivée à un mix BEM et classes utilitaires qui me va bien. Je ne peux me résoudre à tirer un trait sur la lisibilité.
Il y a une question qui est extrêmement utile en dev (et dans plein d'autres domaines j'imagine !) :
"À qui appartient la responsabilité ?"
Le composant parent (BEM) ne doit s'occuper que de lui et de ses enfants. J'entends par enfants, ses bambins qu'il emporte partout avec lui, ceux qui ne sont pas déjà indépendants. Il ne doit pas non plus s'occuper de son positionnement dans la page.
Le positionnement, les espacements, je les laisse aux classes utilitaires. Je n'utilise pratiquement que les classes de display, de margin, et parfois celles de typographie.
C'est pour moi la meilleure approche pour ne pas avoir à ajouter des classes pour tout, tout en restant lisible et scalable.