← Blog · · L'équipe ConvertCaseHQ · 7 min de lecture

Conventions de nommage CSS : kebab-case, BEM et au-delà

La plupart des noms de classes CSS s'écrivent en kebab-case minuscule (.site-header, .price-tag), parce que c'est ainsi que CSS nomme ses propres éléments : background-color, font-size, flex-direction. BEM s'appuie sur cette base avec une structure fixe, block__element--modifier, si bien qu'une classe comme card__title--large vous dit à quel composant elle appartient, de quelle partie de ce composant il s'agit et quelle variante elle affiche.

Au programme : ce à quoi CSS est sensible ou non en matière de casse, pourquoi le kebab-case s'est imposé par défaut, ce que disent vraiment les règles de nommage de BEM, et quand une autre approche rend BEM superflu.

Ce qui est sensible à la casse en CSS, et ce qui ne l'est pas

La syntaxe propre de CSS est insensible à la casse dans la plage ASCII : COLOR: RED fonctionne donc exactement comme color: red. Trois choses se comportent autrement :

  • Les noms de classes sont sensibles à la casse. .Card ne correspondra pas à class="card". Seule exception : une page en mode quirks, où les navigateurs comparent les noms de classes sans tenir compte de la casse, ce qui est une raison de plus de commencer chaque page par <!DOCTYPE html>.
  • Les propriétés personnalisées sont sensibles à la casse. --brand-color et --Brand-Color sont deux variables différentes.
  • Les noms d'éléments et d'attributs HTML ne le sont pas. Dans un document HTML, DIV et div sélectionnent les mêmes éléments. En XML, ils seraient différents.

Le plus simple pour ne plus jamais avoir à y penser : écrivez tous vos noms de classes et toutes vos propriétés personnalisées en minuscules. Pour savoir comment les autres langages et les systèmes de fichiers gèrent la casse, consultez notre comparatif de la sensibilité à la casse.

Pourquoi le kebab-case l'a emporté pour les classes CSS

Rien dans CSS n'impose le kebab-case aux noms de classes. .cardTitle et .card_title sont tous deux valides. Les tirets s'imposent parce que tout ce qui entoure un nom de classe en utilise déjà : les noms de propriétés, des valeurs comme space-between et des attributs HTML comme aria-label et data-user-id. Une classe en camelCase au milieu d'une feuille de style pleine de tirets ressemble à une faute de frappe.

C'est en JavaScript que le kebab-case devient malcommode, car les tirets n'y sont pas autorisés dans les identifiants. Le navigateur gère ses propres cas : data-user-id se lit element.dataset.userId, et background-color devient element.style.backgroundColor. Les noms de classes restent généralement des chaînes (classList.add("is-open")), donc la question ne se pose pas pour eux.

L'exception, ce sont les CSS Modules. Un CSS Module exporte ses noms de classes vers JavaScript sous forme d'objet : .card-title doit alors s'écrire styles["card-title"], alors que .cardTitle donne le plus net styles.cardTitle. C'est la seule configuration dans laquelle nous passerions les noms de classes en camelCase.

Le nommage BEM : bloc, élément, modificateur

BEM (Block, Element, Modifier, soit bloc, élément, modificateur) est né chez Yandex. La page d'historique de la méthodologie fait remonter les travaux à 2005, situe le début de BEM en mars 2009, avec la sortie du framework Lego 2.0 de Yandex, et date le passage à l'open source de 2010. Les règles de nommage sont courtes :

  • Bloc : un composant autonome qui a du sens à lui seul, comme .card, .search-form ou .menu.
  • Élément : une partie d'un bloc qui n'a pas de sens en dehors de lui, nommée selon le schéma bloc, deux tirets bas, élément : .card__title, .menu__item.
  • Modificateur : un indicateur qui change l'apparence, le comportement ou l'état, nommé selon le schéma bloc ou élément, deux traits d'union, modificateur : .card--featured, .card__button--disabled. Un modificateur peut aussi prendre la forme d'une clé et d'une valeur : .form--theme-xmas.

À l'intérieur de chaque partie, les mots sont séparés par un seul trait d'union, comme dans .search-form__submit-button. Voici un composant complet :

<article class="card card--featured">
  <h2 class="card__title">Spring sale</h2>
  <p class="card__body">Everything 20% off this week.</p>
  <a class="card__button card__button--disabled" href="/sale">Shop now</a>
</article>
.card { border: 1px solid #ddd; padding: 1rem; }
.card--featured { border-color: gold; }
.card__title { font-size: 1.25rem; }
.card__button--disabled { opacity: 0.5; pointer-events: none; }

BEM classique ou style à deux tirets

Si vous lisez le site officiel de la méthodologie, bem.info, les modificateurs n'ont pas la même allure. Son schéma classique sépare les modificateurs par un seul tiret bas : menu_hidden, menu__item_visible, menu__item_type_radio. La version en -- y figure comme une alternative, le « Two Dashes style » (style à deux tirets), et c'est celle que documente getbem.com. Les deux sont du BEM tout à fait légitime ; évitez simplement de les mélanger dans une même base de code. bem.info signale aussi un petit piège avec les tirets : un double trait d'union dans un commentaire HTML peut faire échouer la validation.

Les règles BEM qu'on applique souvent mal

  1. Pas d'éléments d'éléments. Un titre placé dans l'en-tête d'une carte reste card__title, pas card__header__title. Vous pouvez imbriquer les éléments aussi profondément que vous le voulez dans le HTML ; les noms, eux, restent à plat. L'argument de bem.info : avec des noms enchaînés, on ne peut pas déplacer, ajouter ou supprimer un élément sans modifier le code existant.
  2. Un modificateur ne s'emploie jamais seul. Écrivez class="button button--primary", pas class="button--primary". Le modificateur ne fait que s'ajouter à la classe de base.
  3. Utilisez des sélecteurs à une seule classe. .card__title, et non .card .card__title ou h2.card__title. L'exception admise est un modificateur de bloc qui modifie ses éléments : .card--featured .card__title.
  4. Nommez les modificateurs d'après leur fonction. Ici, c'est notre avis plutôt qu'une règle BEM : --featured ou --error survivent à une refonte, alors que --yellow devient un mensonge le jour où la couleur de la marque change.
  5. Gardez les points d'accroche JavaScript hors de vos classes de style. Là encore, c'est notre avis : dans les scripts, sélectionnez les éléments par un attribut data comme data-action="close" plutôt que par .card__button, pour qu'un renommage de classe fait pour des raisons de style ne puisse pas casser le comportement.

Renommer un bloc après coup se résume surtout à un rechercher-remplacer. Collez un template dans notre outil Rechercher & remplacer, activez le mode Regex et remplacez card(__|--) par product-card$1 : toutes les classes d'éléments et de modificateurs passent sous le nouveau nom de bloc, et le nombre de correspondances vous indique combien ont changé. Renommez à part la classe card seule, pour ne pas toucher à des mots sans rapport.

Écrire du BEM avec Sass et avec l'imbrication CSS native

Le sélecteur parent de Sass peut ajouter un suffixe au sélecteur extérieur, et sa documentation prend justement BEM comme exemple. L'imbrication CSS native ne le permet pas, et MDN le précise explicitement : un &__title imbriqué est lu comme un sélecteur de type, et ne produira donc pas .card__title.

// Sass: works
.card {
  &__title { font-size: 1.25rem; }    // compiles to .card__title
  &--featured { border-color: gold; } // compiles to .card--featured
}
/* Native CSS nesting: write the full class names */
.card {
  border: 1px solid #ddd;
  &.card--featured { border-color: gold; } /* .card.card--featured */
}
.card__title { font-size: 1.25rem; }

Au-delà de BEM : quand on peut s'en passer

BEM sert à éviter les collisions entre noms de classes et à rendre la structure visible dans une feuille de style globale. Si autre chose règle le problème des collisions, ses noms à rallonge rapportent moins :

  • Les CSS Modules donnent par défaut une portée locale aux noms de classes : un simple .title dans un composant ne peut pas entrer en conflit avec le .title d'un autre.
  • Le CSS utility-first, comme Tailwind, remplace en grande partie les noms de classes personnalisés par des utilitaires prédéfinis comme font-bold : la question du nommage se déplace alors dans vos composants.
  • Les petits sites qui ne comptent qu'une poignée de composants s'en sortent souvent très bien avec du kebab-case simple et un préfixe par composant.

Même dans ces cas, le kebab-case reste le choix par défaut le plus sûr pour tout nom de classe que vous écrivez vous-même.

Les règles de base

  • Du kebab-case en minuscules pour les noms de classes et les propriétés personnalisées, toujours.
  • BEM quand beaucoup de personnes partagent une même feuille de style globale : block__element--modifier, des noms d'éléments à plat, des modificateurs à côté de la classe de base.
  • Des noms de classes en camelCase uniquement quand un outil comme CSS Modules les expose à JavaScript.

Vous transformez un nom de composant en classe ? Tapez « Product Card » dans notre convertisseur de casse et le bouton kebab-case vous donne product-card. Pour les conventions de toutes les autres couches d'un projet, des variables d'environnement aux URL, consultez notre aide-mémoire des styles de casse pour développeurs.

© 2026 ConvertCaseHQ. Tous droits réservés.