ADR-002 — Méthodologie ABEM pour les classes CSS¶
Date : 2026-04-18
Statut : Acceptée — implémentée
Implémentation : 7145e14 (tokens Tailwind + premiers atomes), 400f427 (scaffold 6 sections landing avec préfixes o-), 30ccf57 (refactor MStationCard — preuve que la convention tient hors host), 212193a (purge des valeurs CSS brutes). La convention tient sur l'ensemble des composants shipped à ce jour (2026-04-21) : aucun composant .vue sans préfixe a-/m-/o-/t-/p-.
Contexte¶
Le poste CREALP mentionne explicitement "Atomic Design" comme méthodologie. Il faut une convention de nommage CSS cohérente avec :
- Atomic Design (atoms, molecules, organisms, templates, pages)
- Tailwind CSS (classes utilitaires)
- Composants Vue single-file
Plusieurs conventions candidates : BEM classique, ABEM (Atomic BEM), SMACSS, CUBE CSS, full-utility (Tailwind seul).
Décision¶
On applique ABEM (Atomic BEM), une variante de BEM qui préfixe les blocs par un marqueur atomic design, couplée à Tailwind pour les utilitaires.
Convention précise¶
Structure de classe : [atomic-prefix]-block__element--modifier
Préfixes atomic design :
a-: atom (Button, Badge, Icon)m-: molecule (StationCard, ThresholdBar)o-: organism (StationList, Header)t-: template (MainLayout)p-: page (HomePage, StationDetailPage)
Exemples :
<button class="a-button a-button--primary a-button--lg">
<span class="a-button__icon">...</span>
<span class="a-button__label">Valider</span>
</button>
<article class="m-station-card m-station-card--alert">
<header class="m-station-card__header">
<h3 class="m-station-card__title">Borgne - Bramois</h3>
<span class="m-station-card__badge">Alerte</span>
</header>
<div class="m-station-card__body">...</div>
</article>
Règles d'usage combinées Tailwind¶
- Les classes ABEM décrivent la structure sémantique et portent les variations principales
- Les classes Tailwind dans
@applyau sein des styles scopés des composants (préféré) OU en inline sur les éléments purement utilitaires - Pas de mix inline Tailwind + classe ABEM sémantique sur le même élément en production, sauf pour les spacings contextuels (ex:
class="a-button a-button--primary mt-4"acceptable pourmt-4)
Fichier CSS par composant¶
Chaque composant .vue a une balise <style scoped> qui contient :
- Variables CSS du composant si besoin
- Classes ABEM avec
@applyTailwind
Exemple :
<template>
<button :class="['a-button', `a-button--${variant}`, `a-button--${size}`]">
<slot />
</button>
</template>
<style scoped>
.a-button {
@apply inline-flex items-center justify-center font-medium rounded-md transition-colors;
}
.a-button--primary {
@apply bg-sky-600 text-white hover:bg-sky-700;
}
.a-button--secondary {
@apply bg-slate-200 text-slate-900 hover:bg-slate-300;
}
.a-button--md { @apply px-4 py-2 text-sm; }
.a-button--lg { @apply px-6 py-3 text-base; }
</style>
Conséquences¶
Positives¶
- Lecture du DOM très lisible : on sait immédiatement à quel niveau atomic appartient un élément
- Réutilisation : les classes ABEM peuvent être partagées via un fichier global si un composant est réutilisé entre apps (pas notre cas v1, mais prêt)
- Démonstration explicite d'Atomic Design dans le code (critère recruteur)
- Compatibilité Tailwind : on garde la productivité de Tailwind sans sacrifier la sémantique
Négatives¶
- Overhead vs Tailwind seul : un peu plus verbeux qu'un
<button class="bg-sky-600 px-4 py-2..."> - Discipline requise : il faut respecter la convention systématiquement, sinon incohérence
Alternatives écartées¶
Tailwind utility-only¶
Écartée. Plus productif en pur speed, mais démontre moins explicitement la maîtrise d'Atomic Design. L'annonce cite "Atomic Design" explicitement : on doit le rendre visible dans le code.
BEM classique sans préfixe atomic¶
Écartée. BEM seul ne distingue pas les niveaux atomic. ABEM ajoute cette information pour un coût de 2 caractères.
CUBE CSS¶
Écartée. Méthodologie intéressante mais peu répandue, moins lisible par un recruteur qui n'aurait pas le temps d'apprendre une nouvelle convention pendant la revue.