Au début était la Pangée. Un magma informe, une soupe de balises où se noient des styles épars et obscurs. Tout cela dans un ensemble de code inextricable et bien difficile à comprendre et maintenir !
Et l'on se rendit compte que HTML et CSS étaient tout autant faciles à écrire qu'extrêmement complexes à maintenir, et que seuls certaines sorcières et sorciers étaient capables d'assurer une consistence à leurs incantations codes source.
Les premières méthodologies CSS "grand public" voient le jour dans les années 2008-2009 sous l'impulsion, entre autres, de Nicole Sullivan alors ingénieure chez Facebook qui évoque le terme de "CSS Orienté Objet" ou "OOCSS" notamment lors d'une conférence à Paris-Web.
Méthodologies, Frameworks, Preprocesseurs
À l'instar de véritables langages de programmation, CSS se voit s'articuler autour de lui différentes approches, méthodologies et frameworks.
- Les Approches et méthodologies CSS définissent généralement des règles de nommage ou des bonnes pratiques à suivre.
Les plus utilisées à ce jour sont : OOCSS (Nicole Sullivan), BEM (Yandex), SMACSS (Jonathan Snook), Atomic CSS (Yahoo!) et ITCSS (Harry Roberts) - Les Frameworks CSS : désignent des environnements d'intégration complets et généralement fondés sur l'une des méthodologies sus-citées.
On y trouve par exemple : Bootstrap (historiquement Twitter), Foundation (Zurb), Materialize CSS (Google), Tailwind (Adam Wathan), Bulma (Jeremy Thomas), Tachyons (John Otander) et PureCSS (Yahoo!). Sans oublier KNACSS (Alsacréations) bien sûr ! - Les Pré et post-processeurs : sont des outils permettant de générer ou d'améliorer du code CSS existant. Les plus célèbres étant postCSS (Evil Martians), Sass, LESS et Stylus.
Si l'ensemble de ces approches et outils existent et prospèrent de nos jours, c'est bien parce qu'ils se sont faits leur place dans la réalité des environnements de production.
Comme disaient les cssribes de l'antiquité : "il n'y a pas de bonne ou de mauvaise approche" car :
- Les méthodologies répondent à des besoins
- Les méthodologies évoluent (car les besoins évoluent)
"Être consistant au sein d'une grosse équipe", "Ne pas avoir besoin de toucher au CSS", "Ne pas avoir besoin de comprendre CSS"… sont tout autant de besoins qui peuvent être légitimes.
Certains frameworks, dont Bulma, se targuent d'ailleurs de ne nécessiter aucune compétence en CSS (si cela vous choque… c'est que vous n'en n'avez sans doute pas besoin).
On veut des chiffres !
Si vous aimez les graphiques et les chiffres, sachez que le site web "State of CSS" suit de près les tendances de ce langage :
- État des lieux des méthodologies CSS en 2019
- État des lieux des méthodologies CSS en 2020
- Évolution des frameworks CSS en 2020 (notez les taux de satisfaction, d'intérêt et d'appropriation des différents frameworks)
- Évolution des pré-post processeurs CSS en 2020
L'histoire des approches CSS de IE4 la préhistoire à nos jours
Approche (pré)Historique
La belle époque des <font>
, des <center>
, des <b>
, mais aussi des tableaux de mise en forme à grand renfort de rowspan
, colspan
et autres valign
a longtemps bercé notre enfance d'intégratrice et intégrateur. Les supports navigateurs et les bugs en tout genre complétèrent le tableau (huhu) d'un pseudo-langage bancal qu'était CSS.
Exemple
<div class="center"></div>
<font>
<center>
<b> <!-- j'ai mal rien que d'écrire tout ça --></b>
</center>
</font>
Avantages et inconvénients
Un avantage indéniable est que le terme "center" est parfaitement compréhensible pour un être humain, même un développeur web.
Par contre, un élément <center>
, ou un <div class="center">
, véhiculent des notions purement graphiques, or HTML ne devrait transmettre que des informations de contenu, être dénué de notions de style. En mélangeant allègrement les deux, on complique le rôle et diminue l'intérêt de chacun.
Si cet élément change de style selon le contexte (n'est plus centré sur un grand écran par exemple), le choix de classe devient totalement incohérent. C'est problématique.
Approche Sémantique
Mettons vite le hola à ces pratiques barbares et revenons aux bases que sont :
- le HTML c'est pour la structure et le contenu (le fond)
- le CSS c'est pour la présentation (la forme)
Exemple de sémantique
<div class="container">
<div class="author-info">
<h2>Francis Lalanne</h2>
<img src="" alt="" />
<p class="author-desc">Un troubadour des temps anciens.</p>
</div>
</div>
.author-bio {
...;
}
.author-bio > h2 {
...;
}
.author-bio > img {
...;
}
.author-bio > .author-desc {
...;
}
Avantages et inconvénients
Grâce à ces classes "sémantiques", mon code HTML est propre et pourvu de sens et de logique, et surtout je comprends bien quelle est la fonction de chaque élément (enfin, normalement).
Alors par contre c'est drôle mais cela devient assez vite compliqué de trouver des noms de classe cohérents (salut à toi .modal-wrapper > .inner-content > .warning-global
!).
Avouez que "Nommer les choses en CSS est compliqué" et que depuis l'ère du Responsive et des CSS modernes ça ne va pas en s'arrangeant car il faut aujourd'hui non seulement trouver des noms de classes, mais aussi de variables CSS, de valeurs de Breakpoints, etc.
Fort heureusement, tout le monde utilise de solides Conventions de nommage CSS de nos jours, n'est-il pas ?
En creusant bien, je me heurte à une autre problématique : comme souhaité, mon HTML n'a plus de notions de styles… mais maintenant c'est CSS qui est devenu très dépendant de ma structure HTML car les noms de classes ne contiennent plus aucune information graphique. Je dois systématiquement vérifier mon CSS pour deviner à quoi va ressembler ma classe .warning
. Au final, j'ai simplement retourné la situation, et je n'ai pas séparé HTML de CSS.
Méthodologie BEM
La méthodologie "BEM" (pour "Block Element Modifier") a été élaborée par le moteur de recherche russe Yandex. Elle trouve racine en 2010 mais s'est vraiment activement développée à partir de 2015. Son objectif est de faciliter la réutilisation de composants CSS et d'assurer une cohérence de nommage à travers les équipes et dans la durée.
BEM impose une règle de nommage différente que selon que l'élément soit un "Block" (entité autonome), un "Element" (dépendant d'un Block) ou un "Modifier" (variante de Block ou d'Element).
Trois règles distinguent BEM d'autres approches :
- Tous les éléments HTML doivent chacun avoir un nom sous forme de
class
CSS (pas de nommage viaid
) - Les sélecteurs CSS ne doivent cibler que des classes (pas d'élément tel que
nav
, nia
, niul
dans le nom d'un sélecteur par exemple) - Les sélecteurs CSS composés / hiérarchiques sont à éviter (pas de
.menu .list
, ou de.navigation > a
)
Exemple de BEM
<div class="container">
<div class="author-info">
<h2 class="author-info__title">Francis Lalanne</h2>
<img class="author-info__image" src="" alt="" />
<p class="author-info__desc">Un troubadour des temps anciens.</p>
</div>
</div>
.author-bio {
...;
}
.author-bio__title {
...;
}
.author-bio__image {
...;
}
.author-bio__desc {
...;
}
Avantages et inconvénients
La méthodologie BEM évite toute surprise : sa convention de nommage très stricte permet à coup sûr de comprendre à quoi sert chaque élément mais aussi de choisir le bon nommage quand j'en crée un nouveau. Je comprends ce que mes collègues écrivent et je comprends ce que j'ai moi-même écrit il y a 6 mois dans mon projet.
En outre, la structure HTML peut changer sans aucun impact sur le style (car CSS ne cible que des classes et non des balises HTML).
Enfin, il devient extrêmement facile de maintenir, modifier voire écraser des styles existants puisqu'il n'y a qu'un seul niveau de poids : un sélecteur CSS = une classe unique.
Mais il y a forcément des contreparties…
Mon code HTML a subitement doublé de taille, car chacun des éléments de structure (même s'il n'est pas utilisé) doit avoir un nom de classe à lui, voire plusieurs s'il dispose de variantes.
Et surtout, comment gérer efficacement tous les composants très similaires graphiquement mais dont la fonction est différente (ex. un .article__preview
qui serait quasi identique à un .author__info
) ?
Au final, pour résoudre cette problématique, on ajoutera généralement un niveau d'abstraction plus vaste ("content-agnostic") tel que .card
ou .btn
ou .badge
. Et forcément, la précision et la compréhension en prennent un sale coup.
Approche Atomique
L'approche Atomique (ou "utilitaire") trouve ses origines en octobre 2013 au sein d'un article de Thierry Koblenz sur Smashingmagazine. Cet article donne naissance à ACSS qui est adopté par Yahoo! dès 2015.
Les principes essentiels de cette approche sont :
- À chaque classe CSS correspond une seule fonction (ex.
.txt-left {text-align: left}
ou.mr-2 {margin-right: 2rem}
) - Le styles CSS sont volontairement dénués de contexte (agnostiques) pour être totalement indépendants de la structure HTML
- Les sélecteurs CSS composés n’existent pas (pas de
.menu .list
, ou de.navigation > a
) - Il n'est plus nécessaire d'intervenir dans la feuille de styles CSS. Plus aucun CSS à écrire, modifier ou maintenir car le fichier CSS existe initialement ou est généré au fur et à mesure.
Exemple d'approche atomique
<div class="container md:grid grid-col-3 bg-hotpink p-10 mb-6">
<div class="text-center md:text-left">
<h2 class="text-lg bg-chocolate rounded-full">Francis Lalanne</h2>
<img class="h-16 w-16 md:h-24:w-24" src="" alt="" />
<p class="p-10 my-6 hover:bg-orange">Un troubadour des temps anciens.</p>
</div>
</div>
.text-center {
...;
}
.text-left {
...;
}
.text-lg {
...;
}
.p-10 {
...;
}
Avantages et inconvénients
Atomic CSS, on l'adore ou on le déteste, mais quoi qu'il en soit il est impossible de se tromper dans le nommage ! Il n'y a aucune surprise ni de pièges, personne ne se torture l'esprit ni ne peut bifurquer puisque le nommage existe déjà. Toutes les classes CSS vous attendent, inutile d'en créer davantage.
De plus, je n'ai même plus besoin de fouiller dans mes fichiers CSS, tout se passe côté HTML et je peux me concentrer sur un seul langage lors de mon intégration.
Se fonder sur un nombre de classes existant et restreint m'impose une cohérence (difficile d'avoir 150 niveaux de gris différents par exemple, même si c'est possible.)
Enfin, les contextes d'affichage tels que le Responsive peuvent parfaitement être pris en charge.
Mais encore une fois il y a forcément des contreparties et elles sont de taille
- Ça pique carrément les yeux ! C'est moche. C'est un fait.
- Mon HTML est alourdi, difficile à lire, et contient partout de multiples classes
- Mon CSS, s'il doit prévoir toutes les classes utilitaires dans tous les contextes possibles, aura une taille gigantesque.
- Contrairement aux apparences, j'ai besoin de très bien connaître CSS et toutes ses propriétés pour en déduire toutes les classes utilitaires (oh mais attendez, connaître les CSS n'est pas censé être un inconvénient n'est-ce pas ?)
Mais alors c'est quoi la meilleure méthodologie ?
Pour la petite anecdote, je me souviens très bien du jour où j'ai découvert CSSLint et son incitation à "ne pas utiliser de sélecteur d'ID en CSS". Ma première réaction fut de vivement réfuter en bloc cet argument car la "Bonne Pratique" de l'époque était de cibler les éléments uniques de la page via des #id, et CSSLint allait clairement à l'encontre de toutes nos années d'apprentissage et d'usage de CSS.
J'ai mis quelques années à changer d'avis.
Cet exemple, parmi tant d'autres, démontre qu'une bonne pratique n'est pas figée dans le temps.
Des projets différents impliquent des besoins différents et une approche différente. Tout cela pour conclure qu'aucune approche n'est meilleure qu'une autre car certaines sont parfaitement adaptées à des typologies de projets particuliers, ou aux compétences de l'équipe. Et d'autres non.
Le mot de la fin revient à Thierry Koblenz, ancien chef des experts CSS chez Yahoo!, "inventeur" des CSS atomiques :
Pour Yahoo!, ACSS s’est révélé être un super outil mais si je devais refaire mon site perso demain ce serait certainement 80% sémantique et 20% atomique > (« utility classes »).
Et pour une page toute bête, je pense que ça frôlerait les 99.99% (sémantique ou atomique selon l’humeur du moment).
Source : Thierry Koblenz, 2016
Finalement, vous l'aurez compris, cet article n'avait pas pour but de vous imposer un choix de méthodologie mais plutôt de vous rendre attentif aux avantages et inconvénients de chacune.
N'hésitez pas à enrichir ce débat en avouant votre amour inconditionnel pour Atomic CSS ou votre haine sans fin pour BEM, nous faire découvrir d'autres approches modernes, ou simplement nous témoigner de celle(s) que vous adoptez dans vos projets.
Commentaires
Bravo pour cet article. En voyant l’évolution d’internet, le réchauffement climatique, la surconsommation, etc. J’ai aujourd’hui tendance à vouloir alléger au maximum mon code HTML et CSS afin de limiter l’impact sur l’environnement. Je limite donc mon code générique (suivant le design j’appliquerai ce qui doit être générique ou non) et j’applique de la sémantique (pour de petits\moyens projets). Tout dépend ensuite du projet. Je crois que selon le type et l’envergure d’un projet la méthodologie sera différente. Un site comme par ex. Facebook qui aura des perspectives d’énormes évolutions... à plus intérêt à partir sur de l’atomic pour tout les développeurs/intégrateurs travaillant dessus. Encore une fois cela reste mon humble avis ;-).
Pour en ajouter au moulin, j'avais écrit une très longue série d'articles sur CSS il y a qq années et notamment un sur les approches https://openweb.eu.org/articles/des-approches-en-vogue-confrontees-aux-principes (Atomic n'était pas encore très fréquent à l'époque).
A titre personnel, je mixe BEM pour la convention de nommage, OOCSS pour le côté réutilisable/objet, j'aime bien les classes d'état (avantageusement remplacés par des états sur attributs ARIA quand c'est possible) de SMACSS, et surtout énormément de classes atomiques/helpers pour réduire le poids des CSS (une classe sera utilisée énormément de fois).
Côté règles, toujours la spécificité la plus basse possible pour ne pas avoir un enfer en maintenance. Sass est toujours pratique aussi. Les linters peuvent avoir leur utilité, notamment si des contributeurs non rompus à CSS viennent jouer un peu. Il reste que maintenant, c'est plus vu comme une compétence avancée - JS est tellement mainstream :D
Mais oui, typiquement, selon le type de projet, l'approche ne sera pas la même : sur les interfaces de Proton v4 (plusieurs apps branchées sur les mêmes styles), j'ai un besoin énorme de réduction du poids/réutilisabilité pour éviter de faire enfler les feuilles de style (sujet abordé ici à We Love Speed https://youtu.be/M-0mELaBX8Y certains choix ne sont pertinents qu'à partir d'une certaine échelle), et notamment pour des raisons de maintenance.
C'est clair que pour un petit site perso ou un site vitrine, si 3 sélecteurs sont un peu cracras, c'est pas grave. Sur un design system branché sur 8 apps, avec des tonnes de contraintes métier/perf/maintenance, c'est vraiment pas du tout le même jeu.
Super état des lieux, merci Raphaël !
Pour ma part, j'aime garder quelque chose de sémantique, avec une préférence pour BEM, avant d'avoir commencé avec OOCSS.
J'apprécie énormément le découplage que propose BEM entre le HTML et le CSS, à maintenir, c'est du gâteau (tant que c'est fait correctement et de façon cohérente : j'ai vu des projets revendiquant utiliser BEM - ça peut faire mal aux yeux aussi, et au final, je préfère une approche sémantique maison et cohérente que n'importe quel système mal utilisé).
J'ai beaucoup de mal avec les systèmes atomic : comme tu le dis, ça pique les yeux. Un principe que j'aime retrouver dans tous les langages informatiques, c'est de rester lisible par un humain (j'ouvre le code, je sais ce qu'il fait, à quel endroit il le fait). Quand on voit ACSS (par exemple), c'est quand même tendu niveau lisibilité. Et puis bon, au bout d'un moment, je me dis qu'en allant au bout de la logique, autant directement utiliser l'attribut style (ou les attributs HTML de mise en forme :)).
@enguerranws : Concernant le fait que BEM alourdit le projet, il y a des façons d'y remédier pour garder un site léger en prod, selon la techno, pour compresser les noms de classes en prod (un module Webpack par ex).
@enguerranws : "je me dis qu'en allant au bout de la logique, autant directement utiliser l'attribut style (ou les attributs HTML de mise en forme :)"
Alors non justement, c'est un raccourci que beaucoup prennent, mais il y a une différence énorme avec les styles en ligne. Celui de la spécificité qui reste celle d'une classe CSS et non d'un style= (voir : https://acss.io/frequently-asked-questions.html#how-is-atomic-css-different-than-using-inline-styles- )
«Un magma informe, une soupe de balises où se noient des styles épars et obscurs. Tout cela dans un ensemble de code inextricable et bien difficile à comprendre et maintenir !»
C’est exactement pour les mêmes raisons que je n’utilise pas l’écriture inclusive !
@Raphael : Oui, j’exagère :) Et la couche d'abstraction supplémentaire reste plus utile que l'attribut style. C'est surtout du point de vue de la lisibilité du code que je dis ça.
@enguerranws : Oui, la lisibilité du code est naturellement dégradée. On s'en sort beaucoup mieux avec divers ajouts dédiés, par exemple les plugins VSCode d'autocomplétion et de coloration syntaxique pour Tailwind.
Excellente présentation des "philosophies" CSS ! Merci beaucoup !
Le jeu de mot était voulu ici : « Ma première réaction fut de vivement réfuter en block cet argument » ?
block = bloc ;)
Ou est-ce dû à un excès de codage ? ;D
Une bonne idée de citation au bas du site alsacreations.com je trouve ;)
@jojaba : Oh oui, bien vu ! C'est effectivement un lapsus révélateur :)
Bonjour,
Ca faisait très longtemps que je n'etais revenu sur ce site,... bon je vois que c'est toujours aussi intéressant.
Merci pour cette article, je viens de comprendre et de mettre un mot sur pourquoi je n'ai jamais aimé bootstrap.
Donc pour moi c'est BEM à coup sûr, et le ratio BEM 80%, Atomic 20% me semble plus proche de la réalité (enfin de la mienne biensur ;-) ).
Je trouve que c'est ce qu'il manque dans les formations CSS (je parle en général), c'est de parler plus de méthodologie, nommage, comment organiser son code.
Bonne journée
Sebastien.
@Croquisse : "Je trouve que c'est ce qu'il manque dans les formations CSS (je parle en général), c'est de parler plus de méthodologie, nommage, comment organiser son code."
Je suis tellement d'accord avec toi, c'est un domaine bien trop mal/sous-traité.
La perche est un peu facile pour que je fasse mon "commercial", mais il se trouve justement que notre formation "CSS techniques de pros" est en grande partie axée sur les bonnes pratiques et les méthodologies : https://formations.alsacreations.fr/formation-css3-techniques-pros.html
Merci pour cette article qui m'a beaucoup aidé dans mes choix !
Article que je garde précieusement pour les étudiants ! Merci pour ces ressources très utiles.