Niveau 3 — La Cascade

La cascade

Comprendre l'algorithme de cascade, l'ordre des règles et comment le navigateur résout les conflits de styles.

1. Comprendre la cascade

En une phrase : La cascade est l'algorithme que le navigateur utilise pour déterminer quelles règles CSS s'appliquent et dans quel ordre, quand plusieurs règles ciblent le même élément avec des propriétés conflictuelles.

Le mot « cascade » vient de l'idée que les règles coulent comme un torrent : elles se superposent, se combinent et se disputent la priorité. Le navigateur doit arbitrer ces conflits de manière prévisible et déterministe.

Voici les 5 étapes de l'algorithme de cascade (dans l'ordre de résolution) :

Étape Critère Description
1 Origine et importance D'où vient la règle (user-agent, user, author) et si elle est marquée !important
2 Spécificité La précision du sélecteur (ID > classe > élément)
3 Ordre source Quand tout le reste est égal, la dernière déclaration l'emporte
4 Héritage Certaines propriétés se transmettent aux éléments enfants
5 Proprété par défaut La valeur par défaut du navigateur

2. Syntaxe détaillée

2.1 L'ordre source : la dernière règle gagne

Règle fondamentale : Quand deux règles ont la même origine et la même spécificité, c'est celle qui apparaît la dernière dans le code source qui l'emporte.
/* Règle 1 — apparaît en premier */
p {
  color: blue;
}

/* Règle 2 — apparaît en second */
p {
  color: red;
}

/* Résultat : les paragraphes seront ROUGES
   car la règle 2 est la dernière dans le code */

Cette règle s'applique aussi aux feuilles de style externes : la feuille chargée en dernier a la priorité. C'est pourquoi l'ordre des balises <link> compte :

<!-- L'ordre compte ! -->
<link rel="stylesheet" href="base.css">      <!-- chargé en 1er -->
<link rel="stylesheet" href="composants.css"> <!-- chargé en 2ème -->
<link rel="stylesheet" href="utilities.css">  <!-- chargé en 3ème (gagne en cas de conflit) -->

2.2 Les origines des styles

Concept : Le navigateur gère 3 origines de styles, chacune avec un poids différent dans la cascade.
Origine Source Poids dans la cascade
User-Agent Styles par défaut du navigateur Le plus faible
User Préférences de l'utilisateur (barre d'outis, extensions, userContent.css) Moyen (sauf !important)
Author Styles du développeur (feuilles CSS) Le plus fort (normalement)

Quand !important est utilisé, l'ordre s'inverse pour les origines :

Ordre normal Ordre avec !important
1. User-Agent 3. Author (!important)
2. User 2. User (!important)
3. Author 1. User-Agent (!important)

2.3 Inline, interne et externe

/* CSS externe : style.css */
p {
  color: black;        /* le plus faible des trois */
}

/* CSS interne (dans <style>) */
<style>
  p {
    color: blue;       /* plus fort que l'externe */
  }
</style>

/* CSS inline (dans l'attribut style) */
<p style="color: red;">Texte</p>
                       /* le plus fort des trois sans !important */
Hiérarchie sans !important :
Inline style="" > Interne <style> ≈ Externe .css
Note : interne et externe ont la même origine (author), c'est la spécificité et l'ordre qui les départagent.

2.4 Comment le navigateur résout les conflits

Algorithme simplifié :
1. Regarde l'origine et l'importance (!important)
2. Compare la spécificité des sélecteurs
3. En cas d'égalité, prend la dernière déclaration dans le code source

3. Visualisation

3.1 L'algorithme de cascade

┌─────────────────────────────────────────────────────────────┐
│                  ALGORITHME DE CASCADE                       │
│                                                              │
│  Règle A  ─────┐                                             │
│                │                                             │
│  Règle B  ─────┤   Le navigateur reçoit toutes les règles   │
│                │   qui s'appliquent à l'élément              │
│  Règle C  ─────┘                                             │
│                │                                             │
│                ▼                                             │
│  ┌──────────────────────────────┐                            │
│  │ ÉTAPE 1 : Origine            │                            │
│  │ User-Agent vs User vs Author │                            │
│  │ + !important ?               │                            │
│  └──────────────┬───────────────┘                            │
│                 ▼                                            │
│  ┌──────────────────────────────┐                            │
│  │ ÉTAPE 2 : Spécificité        │                            │
│  │ ID > Classe > Élément        │                            │
│  └──────────────┬───────────────┘                            │
│                 ▼                                            │
│  ┌──────────────────────────────┐                            │
│  │ ÉTAPE 3 : Ordre source       │                            │
│  │ La dernière déclaration gagne│                            │
│  └──────────────┬───────────────┘                            │
│                 ▼                                            │
│  ┌──────────────────────────────┐                            │
│  │ RÉSULTAT : Valeur gagnante   │                            │
│  │ appliquée à l'élément        │                            │
│  └──────────────────────────────┘                            │
└─────────────────────────────────────────────────────────────┘

Les 3 étapes principales de résolution de la cascade

3.2 Ordre source en détail

Ordre de chargement des feuilles de style :
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  <link href="reset.css">     →  chargé 1er  (priorité la plus basse)
  <link href="base.css">     →  chargé 2ème
  <style> ... </style>       →  chargé 3ème
  <p style="color:red">      →  inline      (priorité la plus haute)

En cas de conflit sur la même propriété :
  reset.css: p { color: black; }    ✗ (écrasé)
  base.css:  p { color: blue; }     ✗ (écrasé par style=)
  <style>:   p { color: green; }    ✗ (écrasé par style=)
  inline:    style="color: red"     ✓ GAGNE

L'ordre de chargement détermine le vainqueur en cas d'égalité de spécificité

4. Exemples progressifs

4.1 Deux règles sur le même élément

Démonstration : Conflit simple

/* Règle 1 */
p {
  color: blue;
  font-size: 16px;
}

/* Règle 2 */
p {
  color: red;
  font-weight: bold;
}

Ce paragraphe est rouge et gras — la dernière règle gagne pour color, et c'est la seule pour font-weight.

Deuxième paragraphe — même comportement.

Analyse : color: blue est écrasé par color: red (dernière règle). font-weight: bold s'ajoute car il n'y a pas de conflit. font-size: 16px reste de la règle 1.

4.2 Ordre des feuilles de style

Démonstration : Deux stylesheets

/* base.css — chargé en premier */
p { color: black; }

/* theme.css — chargé en second */
p { color: navy; }

/* Résultat : color: navy gagne (dernière feuille) */

Astuce : C'est pour cela qu'on charge d'abord le reset/base, puis les composants, puis les utilitaires et overrides.

4.3 Spécificité bat l'ordre source

Démonstration : Un sélecteur plus spécifique gagne même s'il vient en premier

/* Règle 1 — spécifique (classe) */
.montitre {
  color: red;
}

/* Règle 2 — moins spécifique (élément), mais en dernier */
h1 {
  color: blue;
}

Ce titre est rouge — la classe gagne même si l'élément vient après

Analyse : La classe .montitre a une spécificité de (0,1,0). Le sélecteur h1 a (0,0,1). La classe gagne même si l'autre règle vient en dernier.

4.4 Inline vs classe vs élément

Démonstration : Trois niveaux de spécificité

/* Élément */
p { color: black; }

/* Classe */
.texte-rouge { color: blue; }

/* Inline */
/* style="color: green" */

Ce paragraphe est vert — inline gagne sur tout

4.5 Cascade avec plusieurs classes

Démonstration : Deux classes sur un même élément

/* HTML : <p class="texte bleu"> */
.texte {
  color: red;
}

.bleu {
  color: blue;
}

/* Résultat : les deux classes ont la même spécificité (0,1,0) */
/* C'est l'ordre source qui départage : .bleu vient en dernier → bleu */

Ce paragraphe est bleu — la dernière classe dans le code source gagne

4.6 Cascade complète avec tous les facteurs

Démonstration : Scénario réaliste

/* Feuille base.css (chargée en 1er) */
p {
  color: black;
}

/* Feuille theme.css (chargée en 2ème) */
p {
  color: navy;
}

/* <style> dans le HTML */
p {
  color: green;
}

/* HTML : <p class="highlight" style="color: orange;"> */

.highlight {
  color: red;
}

Ce paragraphe est orange — le style inline gagne sur tout

Cascade complète : base(noir) → theme(bleu foncé) → <style>(vert) → .highlight(rouge) → inline(orange). Le inline gagne grâce à sa spécificité de (1,0,0,0).

5. Erreurs fréquentes

Erreur 1 : Croire que l'ordre source bat toujours la spécificité
/* FAUX raisonnement : "comme .rouge vient en dernier, ça marchera" */

.rouge {
  color: red;          /* spécificité 0,1,0 */
}

/* Plus tard dans le code... */
#header .titre {
  color: blue;         /* spécificité 1,1,0 — GAGNE même s'il vient en 1er */
}

/* Le sélecteur avec # est toujours plus spécifique */
Erreur 2 : Ne pas comprendre l'impact de l'ordre des feuilles de style
<!-- FAUX — le reset.css écrase les styles personnalisés -->
<link rel="stylesheet" href="mon-style.css">
<link rel="stylesheet" href="reset.css">    <!-- écrase mon-style.css ! -->

<!-- CORRECT — charger le reset en premier -->
<link rel="stylesheet" href="reset.css">
<link rel="stylesheet" href="mon-style.css"> <!-- gagne en cas de conflit -->
Erreur 3 : Penser que le CSS inline est toujours la bonne solution
<!-- FAUX — le inline rend le code impossible à maintenir -->
<div style="color: red; font-size: 20px; padding: 10px; margin: 5px;">
  Texte stylé inline
</div>

<!-- CORRECT — utiliser des classes -->
<div class="alerte">Texte stylé avec des classes</div>
Erreur 4 : Oublier que les propriétés non conflictuelles se combinent
/* Règle 1 */
p {
  color: red;
  font-size: 16px;
}

/* Règle 2 */
p {
  color: blue;
  font-weight: bold;
}

/* Résultat :
   color: blue (conflit — règle 2 gagne)
   font-size: 16px (pas de conflit — conservé)
   font-weight: bold (pas de conflit — ajouté) */

6. Bonnes pratiques

Règles d'or pour gérer la cascade :
  • Ordre logique des feuilles : reset → base → composants → layout → utilitaires → overrides
  • Éviter le CSS inline sauf pour des dynamismes JavaScript ponctuels
  • Utiliser des classes plutôt que des sélecteurs de type pour plus de contrôle
  • Comprendre la cascade avant d'utiliser !important
  • Regrouper les styles par composant dans le même fichier
  • Documenter l'ordre des imports dans un commentaire en haut du fichier principal
/* ✅ Bonne pratique : ordre logique dans un fichier */
/* === RESET === */
/* === VARIABLES === */
/* === BASE / TYPOGRAPHIE === */
/* === COMPOSANTS === */
/* === LAYOUT === */
/* === UTILITAIRES === */
/* === RESPONSIVE === */
Astuce : Si tu te bats constamment avec la cascade pour qu'un style s'applique, c'est probablement que ta hiérarchie de sélecteurs est mal organisée. Revois l'architecture CSS plutôt que d'ajouter des !important.

7. Mini-défi

Exercice 1 : Analyser le conflit

Pour chaque scenario, indique quel style sera appliqué :

/* Règle A */
p { color: black; }

/* Règle B */
p { color: white; }

Question : Quel style gagne pour <p>Test</p> ?

Réponse : color: white — même spécificité, la dernière règle l'emporte.

Exercice 2 : Spécificité vs ordre

/* Règle A */
p { color: red; }

/* Règle B */
.texte { color: blue; }

Question : Avec <p class="texte">Test</p>, quel style gagne ?

Réponse : color: blue — la classe a une spécificité (0,1,0) supérieure à (0,0,1) de l'élément.

Exercice 3 : Trois règles

/* Règle 1 */
p { color: red; }

/* Règle 2 */
p { color: blue; }

/* Règle 3 */
p { color: green; }

Question : Quel style gagne ?

Réponse : color: green — dernière des trois avec la même spécificité.

Exercice 4 : Combinaison

/* Règle A — premier */
.texte { color: red; }

/* Règle B — dernier */
p { color: blue; }

/* HTML : <p class="texte">Test</p> */

Question : Quel style gagne ?

Réponse : color: red — la classe gagne sur l'élément, peu importe l'ordre source.

8. Projet d'application

Projet : Page avec conflits de cascade intentionnels

Crée un fichier index.html et style.css qui démontrent la cascade :

Objectifs :

  • Créer 3 feuilles CSS (base.css, theme.css, override.css) chargées dans l'ordre
  • Écrire des règles conflictuelles dans chaque feuille
  • Ajouter un bloc <style> dans le HTML
  • Utiliser des classes et des sélecteurs d'élément
  • Ajouter au moins un style="" inline
  • Commenter chaque conflit avec l'explication de ce qui gagne et pourquoi

Schéma attendu :

<link rel="stylesheet" href="base.css">       <!-- 1er -->
<link rel="stylesheet" href="theme.css">     <!-- 2ème -->
<link rel="stylesheet" href="override.css">  <!-- 3ème -->

<style>
  /* Bloc 4 — vient après les feuilles externes */
  .titre { color: green; }
</style>

<h1 class="titre" style="color: orange;">
  Titre avec inline (gagne toujours)
</h1>

9. Révision

Quiz rapide

  1. Quand deux règles ont la même spécificité, quelle est la règle de départage ?
  2. Quelles sont les 3 origines de styles dans la cascade ?
  3. Quel est l'ordre des origines en importance croissante (sans !important) ?
  4. Le CSS inline a-t-il toujours priorité sur les sélecteurs de classe ?
  5. L'ordre des balises <link> compte-t-il ?
  6. Deux feuilles CSS définissent p { color: red; } et p { color: blue; }. Laquelle gagne ?
  7. Qu'est-ce qui se passe quand deux règles ont des propriétés non conflictuelles ?
  8. Pourquoi faut-il charger le reset.css en premier ?
  9. Un sélecteur .ma-classe écrit en premier écrase-t-il un sélecteur p écrit en dernier ?
  10. Qu'est-ce que l'algorithme de cascade ?
Réponses :
  1. La dernière déclaration dans le code source l'emporte.
  2. User-Agent (navigateur), User (utilisateur), Author (développeur).
  3. User-Agent < User < Author.
  4. Oui — le CSS inline a une spécificité de (1,0,0,0) qui surpasse n'importe quel sélecteur sans !important.
  5. Oui — la dernière balise <link> a priorité en cas de même spécificité.
  6. p { color: blue; } — celle qui apparaît en dernier dans le code.
  7. Elles se combinent : toutes les propriétés non conflictuelles s'appliquent.
  8. Pour qu'il soit écrasé par les feuilles chargées ensuite en cas de conflit.
  9. Oui — la classe (spécificité 0,1,0) gagne sur l'élément (0,0,1) même en dernier.
  10. C'est l'algorithme du navigateur qui résout les conflits entre règles CSS en fonction de l'origine, de la spécificité et de l'ordre source.