De la feuille de style à l’écran : quel rôle joue CSS dans le pipeline du navigateur
Suivez le CSS de la téléchargement aux pixels : comment le DOM, le CSSOM et l’arbre de rendu sont construits, où s’effectue la cascade des règles, et quels origines de styles concourent pour chaque élément.
La plupart des développeurs écrivent du CSS de manière intuitive : ils modifient une propriété, rechargent la page et vérifient le résultat. Cette méthode fonctionne tant qu’une règle refuse mystérieusement de s’appliquer, qu’une page affiche du contenu non stylisé, ou qu’un changement de style « simple » provoque des ralentissements lors du défilement. Chacun de ces problèmes devient plus facile à comprendre une fois que l’on sait ce que le navigateur fait réellement entre la réception d’un feuille de style et l’affichage des pixels.
Ce guide décrit ce processus de manière globale. Vous verrez comment le navigateur transforme l’HTML en DOM, comment les feuilles de style deviennent CSSOM, comment ces deux éléments se combinent pour former un arbre de rendu, où la cascade résout les déclarations conflictuelles, et quels sont les sources de style qui concourent pour chaque élément. C’est également une question fréquente lors des entretiens, généralement formulée ainsi : « Comment CSS fonctionne-t-il en réalité ? », et la réponse ci-dessous vous offre une manière structurée de y répondre.
Étape un : L’HTML devient le DOM
Lorsque vous ouvrez une URL, le navigateur reçoit d’abord le document HTML. Il analyse le code de balisage de haut en bas et, au fur et à mesure, crée le Document Object Model. Le DOM est un arbre qui représente l’ensemble du document : chaque élément est un nœud, et les nœuds sont reliés entre eux en tant que parents, enfants et frères/sœurs, un peu comme dans un arbre généalogique. Tout ce que décrit l’HTML se trouve désormais dans cette structure, et c’est également ce que JavaScript lit et modifie.
L’analyse s’effectue de manière progressive. Le navigateur ne wait pas que le fichier soit entièrement téléchargé avant de commencer à créer des nœuds, c’est pourquoi il peut découvrir d’autres ressources bien avant que le document ne soit entièrement téléchargé.
Deuxième étape : les feuilles de style deviennent le CSSOM
Lors de l’analyse du HTML, le navigateur rencontre des feuilles de style, qu’elles soient liées avec <link rel="stylesheet"> dans la section head ou intégrées dans des éléments <style>, et commence également à les télécharger et à les analyser. Le CSS est analysé pour former sa propre structure en forme d’arbre, le CSS Object Model, ou CSSOM. Il joue le même rôle pour les styles que le DOM joue pour le marquage.
Transformer le CSS en styles utilisables pour un élément nécessite plus de travail que de transformer du HTML en nœuds. Deux tâches se distinguent :
- Résolution des conflits. Plusieurs déclarations visent souvent la même propriété sur le même élément. Le navigateur résout ces conflits à l’aide d’un algorithme appelé cascade.
2em, 50% ou inherit, ce qui n’est pas encore une valeur utilisable par le moteur de mise en page. Le navigateur convertit ces valeurs en valeurs concrètes.En termes stricts, le CSSOM est la représentation analysée des feuilles de style, et la cascade ainsi que le calcul des valeurs ont lieu lorsque le navigateur détermine le style de chaque élément. Cependant, pour faciliter la compréhension, on peut se représenter cela comme « le CSS est analysé, les conflits sont résolus, les valeurs sont finalisées, et le résultat est appliqué aux éléments ».
Une conséquence pratique : comme le navigateur a besoin des styles avant de pouvoir afficher quoi que ce soit de lisible, les feuilles de style situées dans le bloc head ne sont rendues qu’après avoir été chargées et analysées. C’est pourquoi les feuilles de style volumineuses et lentes retardent la première affichage, et c’est aussi pourquoi il est important de garder le CSS essentiel compact pour améliorer les performances.
Étape trois : le DOM et le CSSOM se combinent pour former l’arbre de rendu
Lorsque le markup est analysé pour former le DOM et que les styles sont transformés en CSSOM, le navigateur fusionne ces deux éléments pour créer un arbre de rendu. Cet arbre contient les nœuds qui seront réellement affichés, chacun associé à ses styles calculés. Les nœuds qui ne produisent aucun résultat visuel, tels que le contenu de <head> ou les éléments avec display: none, sont exclus.
À ce stade, le navigateur sait quoi afficher et comment chaque élément est stylisé, mais il ne connaît pas encore l’emplacement de chacun ni leur taille.
Étape quatre : le layout et le modèle de mise en forme visuelle
Afin de transformer les nœuds stylisés en boîtes positionnées, le navigateur suit ce que les spécifications CSS appellent le modèle de mise en forme visuelle. Cette partie des spécifications CSS décrit comment les éléments de l’arbre du document sont disposés pour les supports visuels tels que l’écran d’un ordinateur portable ou d’un téléphone. Elle couvre le modèle de boîte, la mise en forme en bloc et en ligne, les flottants, la positionnement ainsi que les autres règles qui déterminent la taille et la position de chaque boîte.
Lorsque le layout a calculé la géométrie de chaque boîte, le navigateur les dessine en y insérant du texte, des couleurs, des bordures, des images et des ombres, et le résultat apparaît finalement à l’écran.
Tout le processus en un coup d’œil
En combinant ces étapes, on obtient une séquence simple allant du marquage aux pixels. Chaque flèche cache une quantité importante de travail, mais c’est l’ordre qui est essentiel pour comprendre les bugs et les performances :
HTML
↓
DOM
↓
CSS
↓
CSSOM
↓
DOM + CSSOM
↓
Render Tree
↓
Layout
↓
Paint
↓
Pixels on the Screen
Les navigateurs réels superposent ces étapes et en ajoutent d’autres (comme les couches de composition, par exemple) ; modifier un style ultérieurement peut obliger le navigateur à recalculer les styles, à reconfigurer la mise en page ou à redessiner l’interface, en fonction de la propriété concernée. Pour en savoir plus sur ces coûts, consultez ce que coûte chaque modification CSS au navigateur.
Pourquoi les déclarations entrent en conflit
Le reste de ce guide se concentre sur la première des deux tâches de traitement CSS : la résolution des conflits. L’algorithme responsable est la cascade. Il combine tous les feuilles de style applicables à un document et, chaque fois que plusieurs déclarations définit la même propriété sur le même élément, il décide laquelle l’emporte.
Les conflits sont inévitables, non seulement parce que votre propre feuille de style peut définir la propriété color pour un lien en deux endroits. Les styles proviennent de plusieurs sources indépendantes, appelées origines, et toutes s’appliquent en même temps aux mêmes éléments.
Styles de l’auteur
Ces sont les déclarations que vous et votre équipe écrivez : vos feuilles de style, les blocs <style> et les attributs style en ligne. Sur la plupart des sites, ce sont de loin la source la plus importante de règles.
Styles de l’utilisateur
La personne qui consulte la page peut également influencer les styles. Les navigateurs permettent aux utilisateurs d’ajuster des paramètres tels que la taille de police par défaut, et certains prennent en charge des feuilles de style personnalisées ou des extensions qui y insèrent du contenu. Ces préférences sont particulièrement importantes pour l’accessibilité, car elles permettent aux lecteurs ayant une vision faible ou des difficultés de lecture d’adapter la page à leurs besoins.
Styles de l’agent utilisateur
Finalement, le navigateur (l’agent utilisateur) intègre sa propre feuille de style par défaut. C’est pourquoi un élément <a> non stylisé apparaît en bleu et souligné, pourquoi les titres sont en gras et plus grands que le texte principal, et pourquoi <body> possède un petit marges. Ces paramètres par défaut sont appelés styles d’agent utilisateur.
Lorsque la cascade fusionne ces trois sources, la même propriété sur le même élément peut facilement recevoir plusieurs valeurs concurrentes, et le navigateur a besoin d’une méthode déterministe pour choisir.
Comment la cascade prend-elle sa décision
La cascade compare les déclarations conflictuelles en utilisant une séquence fixe de critères, ne passant au suivant que lorsque le précédent entraîne un match nul :
- Origine et importance. L’endroit d’où provient la déclaration, ainsi que le fait qu’elle soit marquée
!important. - Spécificité. La précision avec laquelle le sélecteur cible l’élément ; un sélecteur par ID l’emporte sur un sélecteur de classe, qui lui-même l’emporte sur un sélecteur de type.
- Ordre d’origine. Si tout le reste est identique, la déclaration qui apparaît plus tard l’emporte.
Classement des origines
Pour le premier critère, l’ordre classique de priorité va du plus élevé au plus bas comme suit :
- Déclarations utilisateur marquées
!important. - Déclarations de l’auteur marquées
!important. - Déclarations normales de l’auteur.
Comprenez bien ce que cela signifie. Vos styles ordinaires prennent le pas sur les préférences habituelles de l’utilisateur ainsi que sur les paramètres par défaut du navigateur, ce qui vous permet justement de concevoir une page. Cependant, !important inverse l’ordre de priorité entre les utilisateurs et les concepteurs : un utilisateur ayant réellement besoin d’une police plus grande ou d’un contraste plus élevé peut marquer cette préférence comme importante, ce qui la rend prioritaire même par rapport à vos règles !important. Les paramètres par défaut du navigateur restent alors en dernier et ne s’appliquent que si personne d’autre n’a défini de règles.
Le CSS moderne affine cette approche. La cascade actuelle prend également en compte les couches de cascade (@layer), les styles définis par des animations et des transitions en cours, ainsi que les déclarations !important des user-agent, qui ont la priorité sur toutes les autres déclarations importantes. La liste simplifiée ci-dessus reflète néanmoins les relations les plus pertinentes au quotidien ; consultez la référence sur la cascade de MDN mentionnée précédemment pour connaître l’ordre complet.
La spécificité et l’ordre de source méritent un traitement détaillé, y compris la manière dont les poids des sélecteurs sont comparés et pourquoi !important provoque souvent plus de problèmes qu’il n’en résout. Cela est abordé dans comment la cascade choisit le gagnant.
Pourquoi ces connaissances sont utiles
Comprendre ce processus modifie la façon dont vous déboguez et écrivez des styles :
- Les règles qui ne s’appliquent pas sont presque toujours des pertes en cascade. Connaître l’ordre d’origine, la spécificité et l’ordre des sources vous indique où chercher plutôt que de recourir à
!important. - Les éléments non stylisés ou stylisés tardivement proviennent de la nature bloquante des feuilles de style ainsi que de styles qui arrivent après le premier rendu.
- Les interactions défaillantes sont souvent dues à des modifications qui obligent à exécuter à nouveau le calcul du layout ou de la peinture des éléments ; vous pouvez les éviter une fois que vous savez à quelle étape une propriété a un impact.
- Un CSS maintenable est généralement un CSS présentant une spécificité faible et prévisible, ainsi qu’un ordre des sources clair, ce qui facilite son traitement tant par le navigateur que par vos collègues.
Conclusion
Le navigateur transforme l’HTML en DOM, les feuilles de style en CSSOM, les combine pour former un arbre de rendu composé de nœuds visibles et stylisés, puis utilise le modèle de mise en forme visuelle pour organiser ces éléments avant de les dessiner. Au stade CSS, la cascade constitue le premier mécanisme de contrôle : elle fusionne les styles de l’auteur, de l’utilisateur et de l’agent utilisateur, résolvant chaque conflit en fonction de leur origine et de leur importance, puis de leur spécificité, et enfin de l’ordre d’apparition des sources. La phase suivante, qui consiste à convertir les valeurs sélectionnées en nombres concrets que le moteur de mise en page peut utiliser, est expliquée dans comment les navigateurs résolvent les valeurs CSS avant la mise en page.