Cascade - noelno/dovelei GitHub Wiki

Important : cet article est partiellement obsolète. Ces informations datent de 2012, le fonctionnement du parseur a été optimisé depuis.

Priorisation des règles CSS

Le parseur est un outil d'analyse du navigateur, qui lui permet notamment de parcourir, de vérifier chacun des éléments HTML, et de leur attribuer le traitement suivant :

I. Récupérer toutes les règles CSS en filtrant par type de composant

Le composant est le dernier sélecteur d'une règle CSS. Par exemple pour la règle div ul .nouveau { ... }, les sélecteurs sont div ul .nouveau et le composant est .nouveau.

Le parseur parcourt toutes les feuilles CSS dans l'ordre suivant :

  • les fichiers CSS auteur externes liés via la balise <link> ou la règle @import
  • les styles auteur inclus dans les balises <style></style>
  • les styles auteur « en-ligne » inclus dans l'attribut style des balises
  • la feuille de style utilisateur, installable dans les binaries du navigateur par l'utilisateur
  • la feuille de style par défaut du navigateur, installée par défaut (IE, Firefox, Webkit...)

Puis il récupère automatiquement :

  • toutes les règles dont le composant cible le bon élément (div, a, p...)
  • toutes les règles universelles (*, [attribut=valeur]...).

Par contre il ignore automatiquement :

  • les règles dont le composant est un identifiant, si l'élément n'a pas d'attribut id
  • les règles dont le composant est une classe, si l'élément n'a pas d'attribut class

Ce procédé permet d'optimiser le temps de parsing, en réduisant le nombre de règles à analyser.

II. Analyser les règles et identifier celles qui ciblent l'élément

Le parseur analyse chaque règle en lisant les morceaux des sélecteurs de droite à gauche, ce qui lui permet de savoir plus rapidement si l'élément est ciblé qu'en procédant de gauche à droite.

Par exemple pour un élément <p class="last"></p> imbriqué dans plusieurs div dont une div ancêtre d'id home, le sélecteur #home div article .last sera analysé de droite à gauche, en commençant par .last et en remontant dans l'arbre du DOM, jusqu'à ce qu'il analyse article et s'aperçoive que le sélecteur ne correspond pas à l'élément.

Si le parseur lisait de gauche à droite, il aurait à analyser plus de mots pour se rendre compte que le sélécteur ne convient pas. Par exemple il analyserait #home div article .first jusqu'au .first.

III. Trier les règles par poids

Par défaut toutes les règles sont alors appliquées à l'élément. Cependant il arrive que la même propriété mais avec des valeurs différentes soit attribuée plusieurs fois au même élément. De plus toute propriété a une valeur par défaut, précisée dans les spécifications CSS.

Pour déterminer quelle règle est prioritaire, on se base sur :

  • en cas d'héritage, la règle dont le sélecteur porte sur l'élément le plus proche possible de l'élément cible est prioritaire, même si un ancêtre a une règle avec la valeur !important (demo)
  • la présence de la valeur !important dans l'une de ces règles : la propriété ayant pour valeur !important est prioritaire sur celles de toutes les autres règles (demo)
  • le poids des sélecteurs de la règle : les styles en ligne ont priorité sur les id, qui ont la priorité sur les classes, qui elles ont la priorité sur les éléments. (demo) Un sélecteur avec deux classes a un poids plus élevé qu'un sélecteur avec une seule.
    Le sélécteur universel, les sélecteurs d'attributs et les pseudo-classes ont le même poids que les classes, sauf :not() qui n'a aucun poids. Par contre le sélécteur que :not a entre parenthèses est compté dans le calcul.
    Les pseudo-elements comptent comme des éléments.

IV. Trier les règles par ordre d'apparition

Deux règles ayant des sélecteurs de même poids se départagent selon leur ordre d'apparition dans la feuille de style, et dans l'ordre de la cascade.

La cascade se fait dans l'ordre suivant :

  • feuilles de style du navigateur
  • feuilles de style de l'utilisateur
  • feuilles de style de l'auteur du site
  • styles importants de l'auteur du site
  • styles importants de l'utilisateur

Pour deux règles de même poids, l'une dans la feuille du navigateur, l'autre dans le style de l'auteur du site, celles de l'auteur l'emportent car apparaissant après.

Recommandations

Pour des questions de performance :

  • limiter le recours aux règles universelles
  • limiter la taille des sélecteurs (nombre de morceaux)
  • éviter de créer un arbre DOM trop profond ou avec beaucoup d'éléments

Sources

⚠️ **GitHub.com Fallback** ⚠️