Héritage

The CSS Podcast - 005: Inheritance

Imaginons que vous venez d'écrire du code CSS pour donner l'apparence d'un bouton à des éléments.

<a href="http://example.com" class="my-button">I am a button link</a>
.my-button {
  display: inline-block;
  padding: 1rem 2rem;
  text-decoration: none;
  background: pink;
  font: inherit;
  text-align: center;
}

Vous ajoutez ensuite un élément de lien à un article de contenu, avec une valeur class de .my-button. Cependant, il y a un problème : le texte n'est pas de la couleur que vous attendiez. Que s'est-il passé ?

Certaines propriétés CSS sont héritées si vous ne spécifiez pas de valeur pour elles. Dans le cas de ce bouton, il a hérité de color à partir de ce CSS:

article a {
  color: maroon;
}

Dans cette leçon, vous allez découvrir pourquoi cela se produit et comment l'héritage est une fonctionnalité puissante qui vous aide à écrire moins de CSS.

Flux d'héritage

Voyons comment fonctionne l'héritage à l'aide de cet extrait de code HTML:

<html>
  <body>
    <article>
      <p>Lorem ipsum dolor sit amet.</p>
    </article>
  </body>
</html>

L'élément racine (<html>) n'hérite de rien, car il s'agit du premier élément du document. Ajoutez du CSS à l'élément HTML, et il commence à se propager dans le document.

html {
  color: lightslategray;
}

La propriété color est héritée par défaut par d'autres éléments. L'élément html a color: lightslategray. Par conséquent, tous les éléments pouvant hériter de la couleur auront désormais une couleur de lightslategray.

body {
  font-size: 1.2em;
}
p {
  font-style: italic;
}

Seul le <p> aura un texte en italique, car il s'agit de l'élément imbriqué le plus profond. L'héritage ne s'applique qu'aux éléments descendants, et non aux éléments parents.

Quelles propriétés sont héritées par défaut ?

Toutes les propriétés CSS ne sont pas héritées par défaut, mais beaucoup le sont. Pour référence, voici la liste complète des propriétés héritées par défaut, tirée de la documentation de référence W3 sur toutes les propriétés CSS:

Fonctionnement de l'héritage

Par défaut, chaque propriété CSS est définie avec une valeur initiale pour chaque élément HTML. Une valeur initiale est une propriété qui n'est pas héritée et qui s'affiche par défaut si la cascade ne parvient pas à calculer une valeur pour cet élément.

Les propriétés pouvant être héritées se propagent de manière descendante, et les éléments enfants reçoivent une valeur calculée qui représente la valeur de leur parent. Cela signifie que si font-weight est défini sur bold pour un parent, tous les éléments enfants seront en gras, sauf si leur font-weight est défini sur une valeur différente ou si la feuille de style de l'agent utilisateur a une valeur pour font-weight pour cet élément.

Hériter et contrôler explicitement l'héritage

L'héritage peut affecter les éléments de manière inattendue. Le CSS dispose donc d'outils pour vous aider.

Le mot clé inherit

Vous pouvez faire hériter n'importe quelle propriété de la valeur calculée de son parent à l'aide du mot clé inherit. Un moyen utile d'utiliser ce mot clé est de créer des exceptions.

strong {
  font-weight: 900;
}

Cet extrait CSS définit la valeur font-weight de tous les éléments <strong> sur 900, au lieu de la valeur par défaut bold, qui correspond à font-weight: 700.

.my-component {
  font-weight: 500;
}

La classe .my-component définit font-weight sur 500 à la place. Pour que les éléments <strong> dans .my-component soient également font-weight: 500, ajoutez:

.my-component strong {
  font-weight: inherit;
}

Les éléments <strong> de .my-component auront désormais un font-weight de 500.

Vous pouvez définir explicitement cette valeur, mais si vous utilisez inherit et que le CSS de .my-component change à l'avenir, vous pouvez vous assurer que votre <strong> sera automatiquement à jour.

Le mot clé initial

L'héritage peut entraîner des problèmes avec vos éléments. initial vous offre une option de réinitialisation efficace.

Vous avez appris précédemment que chaque propriété a une valeur par défaut en CSS. Le mot clé initial rétablit la valeur par défaut initiale d'une propriété.

aside strong {
  font-weight: initial;
}

Cet extrait de code supprime l'épaisseur en gras de tous les éléments <strong> dans un élément <aside> et les rend au lieu de cela d'épaisseur normale, qui est la valeur initiale.

Le mot clé unset

La propriété unset se comporte différemment si une propriété est héritée par défaut ou non. Si une propriété est héritée par défaut, le mot clé unset est identique à inherit. Si la propriété n'est pas héritée par défaut, le mot clé unset est égal à initial.

Il peut être difficile de se souvenir des propriétés CSS héritées par défaut. unset peut être utile dans ce contexte. Par exemple, color est héritée par défaut, mais margin ne l'est pas. Vous pouvez donc écrire ce qui suit:

/* Global color styles for paragraph in authored CSS */
p {
  margin-top: 2em;
  color: goldenrod;
}

/* The p needs to be reset in asides, so you can use unset */
aside p {
  margin: unset;
  color: unset;
}

margin est maintenant supprimé et color redevient la valeur calculée héritée.

Vous pouvez également utiliser la valeur unset avec la propriété all. Pour revenir à l'exemple ci-dessus, que se passe-t-il si les styles p globaux reçoivent quelques propriétés supplémentaires ? Seule la règle définie pour margin et color s'applique.

/* Global color styles for paragraph in authored CSS */
p {
    margin-top: 2em;
    color: goldenrod;
    padding: 2em;
    border: 1px solid;
}

/* Not all properties are accounted for anymore */
aside p {
    margin: unset;
    color: unset;
}

Si vous remplacez la règle aside p par all: unset, les styles globaux appliqués à p à l'avenir n'ont aucune importance, car ils ne seront jamais définis.

aside p {
    margin: unset;
    color: unset;
    all: unset;
}

Vérifier vos connaissances

Tester vos connaissances sur l'héritage

Parmi les propriétés suivantes, lesquelles sont héritées par défaut ?

animation
Les animations ne sont pas transmises aux enfants.
font-size
🎉
color
🎉
text-align
🎉
line-height
🎉

Quelle valeur se comporte comme inherit, sauf s'il n'y a rien à hériter, puis se comporte comme initial ?

reset
n'est pas une valeur valide. Réessayez !
unset
🎉
superset
n'est pas une valeur valide. Réessayez !

Ressources