Votre navigateur n'est pas à jour !

Merci de mettre à jour votre navigateur pour utiliser mon blog. Mettre à jour mon navigateur maintenant

×

CSS - Comment structurer vos sélecteurs CSS

Date de publication 19 mars 2020

La méthodologie CSS


Il existe une multiple de technique pour écrire du CSS maintenable et facile à lire. Je vous propose un petit tour d'horizon de ce que vous pourriez utiliser sur vos projets.
À vous de vous faire votre propre avis, mais mon cœur balance fortement vers une technique, je vous dévoile tout cela !

BEM


J'ai découvert lors d'une conférence la notion de BEM (Block Element Modifier). Derrière cette acronyme se trouve une méthodologie de nommage des classes pouvant s'adapter au CSS / JS : https://en.bem.info/methodology/
BEM gère le nommage des classes et laisse de côté les ID qui sont à proscrire dans votre feuille de style. Les ID ont une portée unique dans la page, la notion de généricité ne s'applique donc pas.
Il est comparable au Web Components qui utilise Shadow DOM, alors que BEM utilise les Block Element.

Un Block est un élément html de la page qui contiendra des enfants. Il encapsule un comportement fonctionnel détaché de la page. Un <ul> peut-être un Block par rapport aux <li>.
Ce Block doit être indépendant et garder son fonctionnement si on le déplace dans la page ou si on le met dans un autre projet.
Il est considéré comme un namespace c'est pour cela qu'il est obligatoire

Un Element est une partie de Block, il ne peut être utilisé en dehors de son Block.
Si plusieurs Element imbriqués existent il faut uniquement préciser le Block et pas tous les Elements
afin que si l'on change un Element de place, aucune modification CSS n'est nécessaire

Un Modifier comprend une paire de clé/valeur ou juste une valeur, qui défini un comportement, il est facultatif.
Par exemple une liste verticale/horizontale ou un élément actif.
Un Modifier peut être associé à un Block ou Element.
La classe du Modifier doit toujours être associé à celle du Block ou Element, car ce Modifier induit un comportement supplémentaire. Il ne faut pas casser la Block ou Element existant

En effet si la classe menu n'existerait pas il faudrait recopier tout le style dans menu_hidden. Avec cette combinaison menu_hidden est une surcharge de la classe menu.
Un Modifier est séparé par un simple underscrore (mais je préfère la syntaxe de Harry Roberts avec double underscore : block-name__elem-name--mod-name__mod-value)

Un préfixe prédéfini peut être envisagé afin de les ranger par groupe mais cela est facultatif dans BEM
  • b- bloc commun
  • l- layout
  • g- styles génériques
  • js- js usage
Il est important de ne pas associer les Block avec un tag html car ce bloc ne serait pas indépendant par rapport à la page.


Pour les noms à donner, BEM préconise l'utilisation de chiffre et caractère minuscule. Le séparateur est un tiret (-) afin de délimiter les mots.

Le choix des noms de variables est un exercice difficile : L'association des Block, Element et Modifier peut avoir un nom de classe extrêmement long. Cela aura un impact sur le chargement de la page mais pas dans l'utilisation de cette classe par JS ou CSS.

Title CSS


BEM peut paraître un peu lourde à mettre en place, alors j'ai choisi de regarder Title CSS
Pour des CSS globales, il utilise une lettre Majuscule et minuscule pour un Modifier ou une classe fille. Cela permet de dire que toutes les classes avec une majuscule ne doivent pas être modifié. En un coup d'oeil cela permet de différencier le Bloc. Ainsi les sélecteurs CSS ressemblent à ce qu'on écrit tous les jours, on commence bien par une Majuscule nos phrases !
De cette manière les sélecteurs sont plus court que BEM.

Par contre un problème survient lorsque les Element sont identiques. Comme les Element ne sont pas précisés et affectés à un bloc il faut préciser ce lien dans notre CSS avec un lien descendant (>)

Cette approche permet de reduire la longueur des noms de classe dans le fichier HTML mais oblige des sélecteurs plus long dans le fichier CSS.
Pour rappel les navigateurs lisent les sélecteurs de droite à gauche, donc si un sélecteur a de nombreux attributs il va beaucoup travailler. Il faut réduire au minimum le nombre de sélecteurs.

L'approche BEM n'a pas ce probleme puisqu'elle combine l'architecture dans le nom de ces classes.

OOCss


Bon pas mieux, on va voir ce que ça donne si en appliquant le concept objet sur les CSS avec OOcss.
C'est une approche objet qui représente un pattern graphique pour HTML/CSS/JS afin qu'il soit réutilisable.
Comme nous le connaissons dans la programmation Objet, il est proposé de séparer la structure et l'aspect et séparer le contenu et le conteneur.
Une classe permettrait de styler un <h2> (en fonction du contenu) sans modifier le comportement basique du h2
.myClass h2 {}
Ce modèle est basé sur YUI module. Plusieurs modules sont disponibles pour prévoir les différents comportements. Par exemple voilà à quoi ressemble un Module bloc qui permet de placer du contenu

Et pour associer un thème il faut placer une classe qui contient uniquement le design du module.

Pour moi cette solution n'apporte pas une lecture facile et nous contraint à utiliser une structure HTML de module bien défini. Il ne serait pas possible de l'utiliser avec un framewok CSS par exemple. D'ailleurs il se rapproche plus d'un framework CSS.

Smacss


SMACSS catégorise en 5 parties ces CSS d'afin avoir des templates pour ne pas refaire du code inutile et améliore la maintenance :
  • Base : c'est la règle par défaut, elle contient un seul attribut. Mais elle peut inclure des sélecteurs avec attributes, pseudo-class selectors, child selectors or sibling selectors
    Il ne doit pas contenir de classe ou ID. Il permet de donner un style identique à des éléments sur une même page.
    Ne pas utiliser !important ici car on définit du CSS général
  • Layout : divise les pages en sections
    Layout est considéré comme un composant majeur, qui est composé de 1 ou plusieurs Module
    Il peut être composé de plusieurs parties : par exemple le Layout est le <body> et les différentes parties sont <header>, <article> et <footer>
    Comme il n'y a pas de namespace sur les nom, on met -l en prefix
    Le premier niveau de Layout est utilisé avec un ID pour le rendre unique
  • Module : doit être réutilisable et indépendant. Il peut ainsi aisément être utilisé à plusieurs endroits dans le Layout
    Il peut être lui-même inclut dans un autre Module
  • State : définit comment le Layout et Module mais dans un état particulier. Sur une autre page, après un événement ...
    L'utilisation de !important ici est autorisé car on cherche à forcer un fonctionnement
  • Theme : s'occupe de l'aspect design : la couleur, la police ...
    Il a un impact sur le Layout, Module et le State

Il est possible d'ajouter un préfixe sur les règles comme -l ou -layout cela permet de trouver facilement l'information dans les fichiers CSS.
Pour les State -is permet aussi d'améliorer la compréhension.
Cependant rajouter module- n'est pas utile car il alourdit le code et n'améliore pas la compréhension.

Pour moi cette solution lie trop fortement la strucutre HTML avec les style CSS. De plus le style CSS mélange des sélecteurs parfois compliqués avec > ou l'utilisation d'ID pour le Layout et de classe pour les Modules.

Conclusion


Compte tenu de mes besoins je me suis orienté naturellement vers BEM car je voulais respecter une méthodologie d'écriture de mes attributs CSS sans alourdir mon projet.
Il oblige en effet à écrire des sélecteurs longs mais cela rend plus maintenable mon code CSS sans me poser la question à quoi correspond ce bout de CSS ou simplement si je vais casser quelque chose en modifiant cet attribut.
Je l'utilise dans tous mes projets maintenant et je trouve cela très pratique.
Au début il faut bien poser les besoins mais une fois que vous aurez bien compris le concept je vous assure que c'est un réflexe.

Je couple cela avec du SCSS pour rendre générique mon CSS.

Et depuis peu je met en place un nouveau framework CSS qui utile BEM Tent CSS pour aller encore plus loin et aussi pour diminuer la taille de mes fichiers CSS provenant de gros framework comme Foundation ou Boostrap.

Et vous que préférez-vous ?
blog comments powered by Disqus