Guillaume Duverger Développeur & graphiste - Blog

Cascade et héritage en CSS

Dernière mise à jour : août 2022

Introduction

Cascade et héritage sont des notions primordiales en CSS. Ce n'est pas anodin si CSS signifie Cascading Style Sheets (feuilles de style en cascade).

Tandis que la cascade s'appuie sur l'ordre d'apparition des styles et la spécificité, l'héritage, lui, repose sur le modèle parent-enfant.

Nous verrons dans ce chapitre comment les notions de cascade, de spécificité et d'héritage se combinent entre elles.


Cascade : ordre et spécificité

L'ordre d'apparition des règles dans le CSS a une importance. Lorsqu'on applique à un élément une même propriété avec une valeur différente, le style prioritaire va être celui qui sera le plus proche de l'élément. Nous allons utiliser la propriété color comme exemple :



h1{

color: red

}

h1{

color: green /*couleur prioritaire !!!*/

}


Ici le sélecteur est le même. La couleur prioritaire de l'élément h1 sera la dernière, à savoir green.

Ce sélecteur est considéré par le navigateur comme ayant une spécificité faible dans la mesure où ce sélecteur cible tous les éléments d'un type donné dans la page.

Voyons un autre exemple pour mieux comprendre le concept de spécificité :



<h1 class="mon-titre">Mon titre en rouge</h1>




.mon-titre{

color: red /*couleur prioritaire !!! spécificité supérieure */

}

h1{

color: green

}

Un sélecteur de classe possèdant plus de poids qu'un sélecteur d'élément, il est donc logique que les styles s'appliquent en priorité. Il existe également d'autres types de sélecteur (voir le chapitre suivant), chacun ayant une place plus ou moins importante dans la hiérarchie de la cascade.

Je vous invite à vous renseigner plus en profondeur sur la spécificité en CSS. Elle mériterait un chapitre à elle-seule.

Les styles ajoutés à un élément directement dans la balise HTML avec l'attribut universel style sont prioritaires par rapport à tout style provenant d'une feuille de style externe ou interne. En effet, cet attribut possède la plus grande spécificité.

L'exception !important

Ce mot-clé est particulier dans le sens où il a la plus grande spécificité dans la cascade (avec l'attribut HTML style, vu plus haut), bien que techniquement ce mot-clé ne fasse pas partie du concept de spécificité. D'où le terme d'exception. Ainsi celui-ci peut-il passer au-dessus du poids et des spécificités de tous les sélecteurs d'un document web.

Il est préférable dans la mesure du possible d'éviter d'utiliser le mot-clé !important qui affecte le traitement naturel de la cascade. Néanmoins, dans certains cas, il peut s'avérer indispensable, notamment lorsqu'on utilise des frameworks (bibliothèques externes) CSS tels que Bootstrap ou Foundation.

Ci-dessous, un exemple de code concret. Nous avons deux paragraphes contenant la même classe. Le deuxième paragraphe contient en plus un identifiant (donc de spécificité supérieure à la classe) où nous avons déclaré une bordure.



#important {
    
background-color: #6753ea;
border: 1px solid black;

}
    
.paragraphe {

background-color: red;
border: none !important;
color: white;
padding: 10px;

}
    
       

En ajoutant le mot-clé !important dans la classe sur la propriété border dont nous indiquons que nous souhaitons pas de bordure. Le résultat est bien ce que nous attendons : aucune bordure ni sur la classe ni sur l'identifiant.

Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Lorem ipsum dolor sit amet, consectetur adipiscing elit.


Héritage : le modèle Parent-Enfant

Le modèle parent-enfant se représente de cette manière :


<body>
 <h1>Je suis l'enfant de l'élément body</h1>
   <div>
      <p>Enfant de div
         <span>Enfant de div et p</span>
     </p>
   </div>
</body>

Chaque élément enfant hérite de tous les styles de son élément parent. Cet héritage s'avère très pratique car celui-ci permet d'éviter les redondances.

Par exemple, l'élément html est le parent de l'élément body et de tous les enfants dans le reste du document. C'est d'ailleurs le seul élément à n'avoir aucun parent.

L'héritage ne fonctionne pas sur toutes les propriétés, notamment sur les propriétés de boîte, telles que la largeur, les marges, le rembourrage et les bordures.

Si vous attribuez une propriété de police de caractères avec la propriété font-family à un parent, elle sera transmise à tous ses enfants, ainsi qu'aux enfants de ses enfants.



html {

font-family: 'Lato', sans-serif;

}  


Dans le code ci-dessus, nous avons déclaré une police à l'ensemble du document via le sélecteur html. Donc tous les enfants du document auront cette police de caractères, à moins bien entendu de déclarer une autre police à un élément.

Le cas de l'héritage de la taille des polices

Le cas de la taille des polices de caractères est intéressant pour comprendre la notion d'héritage. Habituellement, la taille de police racine par défaut est 16px dont la correspondance en unité relative em ou rem est 1(r)em. On parle de pixel CSS qui est différent d'un pixel d'un écran. Je vous invite à vous renseigner (EN) à ce sujet.

A première vue, ces deux unités sont semblables. Il subsite pourtant une différence et non des moindres. Tandis l'unité rem est calculée par rapport à la taille de la police en pixels de l'élément racine (html), l'unité em est calculée en prenant en compte l'héritage des éléments parents. Observez ce code :



<section>

 <div class="contenu">
   
   <div>
  
</section>	




html {

  font-size: 16px; /* taille de police du navigateur par défaut -ne faîtes ceci, c'est pour l'exemple */
}

section {
  font-size: 1.5em; /* 16 x 1.5 = 24px */
  font-size:1.5rem /* 16 x 1.5 = 24px */
}

.contenu {

  padding: 2em; /* 24 x 2 = 48px */
  padding: 2rem; /* 32px */
  
}


Vous l'aurez compris, la valeur calculée d'une propriété s'ajoute par héritage avec l'unité em.

Évitez de déclarer une unité en pixel sur l'élément racine. En effet, si je définis une taille de 10px sur l'ensemble de mon site et qu'un utilisateur décide d'augmenter (ou de réduire pourquoi pas) la taille sur son navigateur, le texte ne changera pas de taille. C'est donc une contre-pratique pour l'accessibilité.

Contrôler l'héritage

Il existe quatre valeurs universelles pour contrôler l'héritage. Celles-ci sont applicables à toute propriété CSS :

  • inherit
  • initial
  • unset
  • revert

Avant de détailler ces quatre valeurs, il faut savoir que chaque propriété CSS possède une valeur initiale. Mais il n'existe aucun lien entre la valeur initiale en CSS et le type d'élément HTML auquel elle s'applique. Après avoir appliqué les styles initiaux de toutes les propriétés CSS, le navigateur charge ses propres styles.

Le mot-clé inherit

La propriété correspondante prend la valeur définie dans l'élément parent. Cela a pour conséquence de "forcer" l'héritage, notamment pour les propriétés qui ne s'héritent pas.

Voici une situation où cette valeur prend tout son sens. Bien que les propriétés de police s'héritent, ce n'est pas le cas sur les éléments de formulaire ; le navigateur chargeant ses propres styles.



form {

font-family: 'Lato', sans-serif;
font-size: 1.25rem;
} 


input,
button,
textarea,
select {

/*On force l'héritage*/

font-family: inherit;
font-size: inherit;

}  


Le mot-clé initial

Si vous avez été attentif, nous avons précisé que chaque propriété en CSS a une valeur par défaut sans correspondance avec la valeur par défaut de l'agent utilisateur.

Le mot-clé initial indique au navigateur d'utiliser la valeur par défaut CSS de la propriété. Si aucune valeur n'est définie par défaut dans le navigateur et que la propriété est transmise par héritage, alors la propriété est redéfinie à inherit.

Un bon exemple pour illustrer le fonctionnement de cette valeur est la suivante :



div{ 
    
    display: initial; 
	
}	 


Le navigateur affiche les élément div avec la valeur block. Quel sera l'état de cet élément si l'on déclare le mot-clé initial ? Il sera de type inline qui est la valeur par défaut de la propriété display.

Le mot-clé unset

Le mot-clé unset est identique à initial en ce qui concerne les propriétés non-héritées. En revanche, il fonctionne comme le mot-clé inherit sur les propriétés héritées.

En regardant ce code, vous allez comprendre :



div{ 
    
color: unset; /* propriété héritée */ 
display: unset; /* propriété non héritée*/ 
	
}	 


Pour la propriété color, le navigateur va remonter la cascade jusqu'à trouver un élément parent avec une définition de la propriété et s'il ne trouve rien, il appliquera son style, à savoir CanvasText (couleur noire). En ce qui concerne la propriété display, ce sera son état initial (comme nous l'avons vu juste avant).

Par ailleurs, au lieu de réinitialiser les propriétés une à une, vous pouvez utiliser la propriété all comme ceci :



div{ 
    
all: unset; 

}	 


Le mot-clé revert

Le mot-clé revert est assez similaire à unset à la seule différence qu'il réinitialise les styles de l'agent utilisateur au lieu du style de base de CSS.



div{

    display: revert; /* = block */ 
	
}


haut page