paint-brush
Nous sommes en 2023, mais nous devons encore parler des styles imbriqués dans CSSpar@lastcallofsummer
3,720 lectures
3,720 lectures

Nous sommes en 2023, mais nous devons encore parler des styles imbriqués dans CSS

par Olga Stogova8m2023/07/17
Read on Terminal Reader

Trop long; Pour lire

Les styles profondément imbriqués entraînent souvent des conflits de style, surtout si vous avez un gros projet. Cela peut entraîner des incohérences visuelles inattendues et beaucoup de temps perdu. Le concept de spécificité (ou le « poids » des styles) en CSS est crucial pour comprendre pourquoi l'imbrication profonde peut être gênante.
featured image - Nous sommes en 2023, mais nous devons encore parler des styles imbriqués dans CSS
Olga Stogova HackerNoon profile picture
0-item

Même une image aléatoire pour la requête "Styles CSS" contient des styles imbriqués.


En tant que développeur frontend avec près de 15 ans d'expérience, j'ai été témoin de l'évolution du développement Web. Pour moi, cela a parcouru un long chemin depuis l'époque du téléchargement de fichiers modifiés via FTP (oui, GitHub a été lancé il y a 15 ans, mais je ne l'ai découvert qu'en 2011) à l'ère moderne des interfaces réactives, des bibliothèques d'interface utilisateur et des sites Web directement générés à partir de Figma.


Pourtant, je rencontre toujours des projets qui utilisent des styles imbriqués comme :


 .some-class ul li div a { /* some style */ }


ou,


 #nav .nav-link svg { /* some style */ }


Cela peut sembler choquant, mais de telles pratiques de codage imprègnent tout, des projets de plusieurs millions de dollars à croissance rapide aux humbles startups.


Voyons pourquoi cette approche peut poser des problèmes.

Le conflit des styles imbriqués

Les styles profondément imbriqués entraînent souvent des conflits de style, surtout si vous avez un gros projet. CSS, en tant que feuille de style en cascade, descend en cascade et s'applique aux éléments en fonction de leur spécificité. Les styles profondément imbriqués peuvent involontairement remplacer d'autres styles en raison de leur spécificité.


Considérez cet exemple :


 .some-class ul li div a { color: red; } ... .some-class a { color: blue; }


Vous pouvez vous attendre à ce que tous les liens dans .some-class soient bleus. Cependant, en raison de la plus grande spécificité de la première règle, tout lien imbriqué dans un ul > li > div sera rouge et non bleu. Cela peut entraîner des incohérences visuelles inattendues et beaucoup de temps perdu à déboguer.

La complexité de la spécificité

Comprendre le concept de spécificité (ou le « poids » des styles) en CSS est essentiel pour comprendre pourquoi l'imbrication profonde peut être gênante. La spécificité détermine quelle règle CSS s'applique si plusieurs règles sont en concurrence pour un seul élément. Il est calculé en fonction du type et de la quantité de sélecteurs.


La spécificité est calculée sur la base d'un système de pondération à quatre catégories :


  1. Styles en ligne
  2. identifiants
  3. Classes, attributs et pseudo-classes
  4. Eléments et pseudo-éléments


Ici, considérons la règle:


 body #content .data img:hover { /* some style */ }


La spécificité est 0 1 2 2 . C'est un ID ( #content ), deux classes ( .data et :hover ) et deux éléments ( body et img ).


Maintenant, considérons la règle :


 #nav .nav-link svg { /* some style */ }


La spécificité ici est 0 1 1 1 . C'est un ID ( #nav ), une classe ( .nav-link ) et un élément ( svg ).


La spécificité ne fonctionne pas sur un système de "report" comme les nombres décimaux traditionnels. Par exemple, un sélecteur avec une spécificité de 0 1 0 11 n'est pas égal à une spécificité de 0 1 1 1 même si dans un système décimal, 11 et 1+1 seraient équivalents.


Enfin, le sélecteur universel ( * ), les combinateurs ( + , > , ~ , ' ') et la pseudo-classe de négation ( :not() ) n'ont aucun effet sur la spécificité. À l'intérieur de l'argument :not() , cependant, les sélecteurs sont comptés comme d'habitude.


Pour les apprenants visuels, je recommande cette vidéo sur la spécificité CSS.


Comprendre la spécificité CSS et la façon dont elle est calculée vous permet d'écrire un CSS meilleur et plus prévisible et de déboguer les problèmes lorsque les styles ne sont pas appliqués comme prévu.

La !important et la spécificité

Parfois, les développeurs ont recours à la règle !important lorsqu'ils rencontrent des difficultés avec des conflits de spécificité CSS. Cette règle rend une propriété CSS extrêmement spécifique, ce qui signifie qu'elle remplacera presque toute autre déclaration.


Par exemple:


 #nav .nav-link svg { color: blue; } .nav-link svg { color: red !important; }


Bien que la première règle ait une spécificité plus élevée en raison du sélecteur d'ID, la couleur du svg serait rouge à cause du !important dans la deuxième règle.

Les risques d'une surutilisation !important

Bien que !important puisse être une solution rapide aux problèmes de spécificité, il n'est pas recommandé de l'utiliser de manière intensive. Une utilisation excessive peut affecter la maintenabilité, la prévisibilité et les performances. Dans les grands projets, la surutilisation de !important indique souvent une difficulté à gérer la spécificité CSS. Plutôt que de recourir à !important , il est souvent préférable d'investir du temps dans la refactorisation de votre CSS et de réduire l'utilisation de sélecteurs trop spécifiques.


Vous pouvez vérifier votre produit dès maintenant 🙂. J'ai vérifié le mien :


111 résultats en 55 dossiers, pas mal pour un gros produit !


Bien que !important puisse être une solution rapide tentante ; c'est comme utiliser un marteau pour casser une noix. Une approche plus maintenable consiste à garder vos sélecteurs aussi simples et aussi plats que possible, ce qui rend votre CSS plus facile à comprendre, à gérer et à étendre à l'avenir. Et rappelez-vous, la meilleure façon de gagner une guerre !important n'est pas d'en commencer une en premier lieu.

Parcourir l'arborescence CSS

Un autre problème avec les styles profondément imbriqués est l'impact des performances sur le rendu du navigateur. Lorsqu'un navigateur applique des styles à un élément, il parcourt le DOM de droite à gauche, en commençant par le sélecteur de clé (dans nos exemples, a et svg ) et en se déplaçant à travers les ancêtres jusqu'à ce qu'il trouve une correspondance ou atteigne le sommet. Plus le style est imbriqué, plus cette traversée prend de temps, ce qui peut affecter les performances et ralentir les temps de chargement des pages dans les projets à grande échelle.


Lorsque vous spécifiez une règle CSS, comme :


 .some-class ul li a { /* some style */ }


Vous pouvez visualiser cette règle en partant du bas de l'arborescence (à partir de la balise a ) et en remontant dans l'arborescence (via li , ul et .some-class ).



juste une petite partie du modèle d'objet CSS



Le navigateur cherchera d'abord tous (je veux dire TOUS) a éléments a, puis il vérifiera si ces a a sont à l'intérieur des éléments li . Après cela, il vérifiera si ces éléments li sont à l'intérieur ul Et enfin, il vérifiera si ces ul sont à l'intérieur d'un élément avec la classe de .some-class .


C'est ainsi que les navigateurs lisent les sélecteurs CSS et la raison pour laquelle les sélecteurs complexes peuvent ralentir le rendu des pages. Le navigateur doit effectuer plusieurs vérifications pour chaque élément pour voir s'il correspond à la règle spécifiée. Plus la règle est profonde, plus le navigateur doit effectuer de vérifications, ce qui peut avoir un impact sur les performances.

Meilleures pratiques pour la gestion du CSS dans les grands projets

Modules CSS

Les modules CSS vous permettent d'écrire du CSS dans des modules individuels, qui sont limités localement au composant sur lequel vous travaillez. Cela signifie que les styles d'un module CSS ne s'appliquent qu'à ce module spécifique et ne fuiront pas ou n'affecteront pas les autres éléments de la page.


Explorons comment les modules CSS utilisent des noms de classe hachés pour assurer l'encapsulation du style. Lorsque vous utilisez des modules CSS, les noms de classe que vous définissez dans votre fichier CSS seront hachés au moment de la compilation. Ce hachage crée un nom de classe unique qui correspond à votre composant. Prenons un exemple :


Supposons que vous ayez un module CSS défini comme tel :


 /* Button.module.css */ .button { color: white; background-color: blue; }


Et vous l'utilisez dans votre composant comme ceci (je préfère importer l'objet styles en tant que s au lieu de styles - une astuce rapide qui permet de gagner du temps de frappe et d'améliorer l'efficacité du codage) :


 import React from 'react'; import s from './Button.module.css'; const Button = () => { return ( <button className={s.button}>Click me</button> ); }; export default Button;


Lorsque votre application est compilée, votre code HTML rendu peut ressembler à ceci :


 <button class="Button_button__3FQ9Z">Click me</button>


Dans ce cas, Button_button__3FQ9Z est le nom de classe haché qui a été généré à partir de votre module CSS. Notez que la structure et la longueur exactes du hachage peuvent varier en fonction de la configuration de votre projet.


Ce nom de classe unique garantit que les styles que vous avez définis dans Button.module.css s'appliquent uniquement à ce bouton et n'affectent aucun autre élément de votre application. Cela garantit également qu'aucun autre style ne peut affecter ce bouton à moins qu'il ne cible explicitement le nom de la classe hachée. Cette encapsulation des styles est l'un des principaux avantages des modules CSS.

Bibliothèques CSS dans JS

Une autre façon populaire de gérer CSS consiste à utiliser des bibliothèques CSS-in-JS, telles que styled-components ou emotion . Ces bibliothèques vous permettent d'écrire votre CSS directement dans votre JavaScript, ce qui présente plusieurs avantages :


  1. Styles étendus : Semblables aux modules CSS, les styles sont étendus au composant dans lequel ils sont définis.
  2. Styles dynamiques : il est facile de créer des styles dynamiques basés sur les accessoires ou l'état de votre composant.
  3. Expérience de développement améliorée : vous pouvez utiliser la logique JavaScript directement dans vos styles, et tout ce qui concerne un composant est situé au même endroit, ce qui peut rendre votre code plus facile à comprendre et à utiliser.


Voici un exemple de la façon dont vous pouvez utiliser des composants de style dans une application React :


 import React from 'react'; import styled from 'styled-components'; const Button = styled.button` color: white; background-color: ${(props) => props.primary ? 'blue' : 'gray'}; `; const App = () => { return ( <div> <Button primary>Primary Button</Button> <Button>Secondary Button</Button> </div> ); }; export default App;


Dans cet exemple, le composant Button a des styles dynamiques qui changent en fonction de son accessoire primary .

Méthodologie BEM

Si vous ne travaillez pas avec un framework JavaScript prenant en charge les modules CSS ou similaires, vous pouvez toujours gérer efficacement votre CSS en utilisant des méthodologies de dénomination telles que BEM (Block, Element, Modifier).


BEM signifie "Block Element Modifier", et c'est une méthodologie qui vous aide à créer des composants réutilisables et à partager du code dans CSS. Voici comment vous pouvez structurer votre CSS à l'aide de BEM :


 /* Block */ .top-menu { } /* Element */ .top-menu__item { } /* Modifier */ .top-menu__item_active { }


Dans BEM, le « Bloc » est l'entité autonome qui a du sens en soi, l'« Élément » est une partie du Bloc qui n'a pas de sens autonome et est sémantiquement lié à son Bloc, et le « Modificateur » est un indicateur sur un bloc ou un élément utilisé pour modifier l'apparence ou le comportement.


L'utilisation d'une méthodologie cohérente telle que BEM peut faciliter la compréhension et la maintenance de votre CSS, en particulier pour les grands projets.

En conclusion

Il existe plusieurs façons de gérer CSS dans des projets plus importants, des modules CSS et des bibliothèques CSS-in-JS aux méthodologies de dénomination comme BEM. La clé est de trouver une approche qui correspond bien à votre équipe et à votre projet et de l'appliquer de manière cohérente. N'oubliez pas qu'écrire du CSS consiste autant à écrire du code efficace et performant qu'à écrire du code compréhensible et maintenable.


Bon codage !