Définir color: #1a1a1a; sur le body suffit en général à colorer tout le texte du site, sans jamais toucher un seul autre élément. Définir margin: 40px; sur ce même body, en revanche, ne donne aucune marge aux paragraphes qu'il contient. Le même mécanisme CSS explique les deux résultats opposés : l'héritage.
Comprendre quelles propriétés héritent et lesquelles n'héritent jamais évite deux erreurs fréquentes : écrire une règle redondante sur chaque enfant alors qu'une seule sur le parent suffirait, ou au contraire attendre d'un enfant qu'il hérite d'une propriété qui ne le fait tout simplement pas.
Définition
L'héritage CSS est le mécanisme par lequel un élément reprend, pour certaines propriétés seulement, la valeur calculée de son parent quand aucune règle ne lui en donne une explicitement. Ce n'est pas une propagation générale : chaque propriété CSS est classée une fois pour toutes, dans la spécification, comme héritée ou non héritée.
body {
color: #1a1a1a;
font-family: system-ui, sans-serif;
}
/* aucun span, p ou li n'a besoin de répéter
ces deux lignes : ils héritent déjà */La Cascade décide quelle règle s'applique quand plusieurs se disputent un élément ; l'héritage, lui, intervient seulement quand aucune règle ne s'applique du tout, et va chercher une valeur chez le parent plutôt que d'utiliser la valeur par défaut du navigateur.
Ce qui hérite, et ce qui n'hérite jamais
La règle générale est simple à retenir : tout ce qui concerne le texte hérite, tout ce qui concerne la boîte n'hérite pas.
| Hérite | N'hérite jamais |
|---|---|
Couleur CSS (color) | margin |
font-family, font-size, font-weight | padding et border |
line-height, text-align | background et background-color |
visibility, cursor | width, height, display, position |
Cette liste n'est pas figée par habitude : elle correspond à une distinction entre ce qui décrit un texte, qui a du sens à s'appliquer uniformément sur un paragraphe entier, et ce qui décrit une boîte, qui doit rester propre à chaque élément.
Pourquoi ce choix est volontaire
Imaginez que margin hérite comme color. Chaque div imbriqué récupérerait la marge de son parent en plus de la sienne, et l'écart entre deux blocs grandirait à chaque niveau d'imbrication sans qu'aucune règle explicite ne le demande. La mise en page deviendrait imprévisible dès qu'un composant serait déplacé d'un niveau à un autre.
À l'inverse, si color n'héritait pas, il faudrait répéter la couleur du texte sur chaque balise, y compris à l'intérieur d'un lien, d'un span ou d'une liste, ce qui rendrait la moindre refonte de charte graphique interminable. L'héritage sert donc la cohérence typographique sans jamais menacer la structure de la mise en page.
button, input, select, textarea) font exception : la plupart des navigateurs leur appliquent une police par défaut qui n'hérite pas de la police du site. Ajoutez font: inherit; sur ces éléments si vous voulez qu'ils suivent réellement la charte définie plus haut.Forcer ou bloquer l'héritage
Une propriété non héritée peut recevoir la valeur du parent quand même, avec le mot-clé inherit. C'est ce que fait justement font: inherit; plus haut : il force l'héritage sur une propriété qui ne le fait pas par défaut. À l'inverse, un enfant peut couper une chaîne d'héritage en cours en réaffirmant sa propre valeur, ce qui arrête la transmission pour lui et pour ses propres enfants. Les Valeurs CSS globales couvrent ces cas plus en détail, avec trois autres mots-clés qui complètent inherit.
Questions fréquentes
body ?Parce que les éléments de formulaire ne suivent pas l'héritage habituel de la police et de la couleur : les navigateurs leur imposent leur propre style par défaut. La correction courante consiste à écrire button, input, select, textarea { font: inherit; color: inherit; } une fois dans la feuille de style globale.
border sur un conteneur, mes enfants ont-ils une bordure aussi ?Non, jamais : border ne fait partie d'aucune version de la liste des propriétés héritées. Seul l'élément sur lequel la règle est écrite reçoit la bordure ; ses enfants n'en héritent à aucun moment, même indirectement.
En lui donnant explicitement la valeur inherit, par exemple background-color: inherit;. L'élément va alors chercher la valeur calculée de son parent pour cette propriété précise, exactement comme s'il s'agissait d'une propriété héritée par défaut, sans qu'aucune autre écriture ne soit nécessaire.