Herança

Digamos que você acabou de escrever algum CSS para fazer com que os elementos pareçam um botão.

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

Então você adiciona um link em um article, com uma classe .my-button. No entanto, há um problema, o texto não tem a cor que você esperava. Como isso aconteceu?

Algumas propriedades CSS são herdadas se você não especificar um valor para elas. No caso desse botão, ele herdou a color deste CSS:

article a {
  color: maroon;
}

Nesta lição, você aprenderá por que isso acontece e como a herança é um recurso poderoso para ajudá-lo a escrever menos CSS.

Fluxo da Herança

Vamos dar uma olhada em como a herança funciona, usando este trecho de HTML:

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

O elemento raiz (<html>) não herdará nada porque é o primeiro elemento do documento. Adicione um pouco de CSS no elemento HTML, e ele começará a se propagar pelo documento.

html {
  color: lightslategray;
}

A propriedade color é herdada por outros elementos. O elemento html tem color: lightslategray, portanto, todos os elementos que podem herdar cores agora terão a cor lightslategray.

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

Apenas o <p> terá texto em itálico porque é o elemento aninhado mais profundo. A herança propaga apenas para baixo, e não para cima, para os elementos pai.

Quais propriedades são herdáveis?

Nem todas as propriedades CSS são herdáveis, mas há muitas que são. Para referência, aqui está a lista completa de propriedades herdáveis, retirado da referência W3 de todas as propriedades CSS:

Como a herença funciona

Cada elemento HTML tem propriedades CSS definidas com um valor inicial por padrão. Um valor inicial é uma propriedade que não é herdada e aparece como padrão caso a cascata não compute um valor para esse elemento.

Propriedades podem ser herdadas em sua propagação para baixo, e os elementos filho obterão um valor computado que representa o valor de seu pai. Isso significa que, se um pai tiver font-weight definido como bold, todos os elementos filho estarão em negrito, a menos que o font-weight seja definido com um valor diferente, ou o user agent stylesheet tenha um valor de font-weight para esse elemento.

Como herdar e controlar explicitamente a herança

A herança pode afetar os elementos de maneiras inesperadas, então o CSS tem ferramentas para ajudar nisso.

A palavra-chave inherit

Você pode fazer qualquer propriedade herdar o valor computado de seu pai com a palavra-chave inherit. Uma maneira útil de usar essa palavra-chave é criar exceções.

strong {
  font-weight: 900;
}

Esse trecho CSS define para todos os elementos <strong> ter um font-weight de 900, em vez do valor padrão bold, que seria o equivalente a font-weight: 700.

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

A classe .my-component define o font-weight como 500. Para definir os elementos <strong> dentro de .my-component como font-weight: 500, adicione:

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

Agora, os elementos <strong> dentro de .my-component terão um font-weight de 500.

Você pode definir explicitamente esse valor, mas se você usar inherit e o CSS de .my-component mudar futuramente, você pode garantir que seu <strong> automaticamente se manterá atualizado.

A palavra-chave initial

A herança pode causar problemas com seus elementos e initial fornece uma poderosa opção de reset.

Você aprendeu anteriormente que toda propriedade CSS tem um valor padrão. A palavra-chave initial define o valor inicial padrão de uma propriedade.

aside strong {
  font-weight: initial;
}

Esse trecho removerá o negrito de todos os elementos <strong> dentro de um elemento <aside> e, em vez disso, tornará todos em normal, que é o valor inicial.

A palavra-chave unset

A propriedade unset se comporta de forma diferente se uma propriedade é herdável ou não. Se uma propriedade é herdável, a palavra-chave unset será a mesma que inherit. Se a propriedade não for herdável, unset será igual a initial.

Lembrar quais propriedades CSS são herdáveis pode ser difícil, unset pode ser útil nesse contexto. Por exemplo, color é herdável, mas margin não é, então você pode escrever isso:

/* Estilos de cores globais para parágrafo em CSS autoral */
p {
  margin-top: 2em;
  color: goldenrod;
}

/* O p precisa ser resetado nos asides, então você pode usar unset */
aside p {
  margin: unset;
  color: unset;
}

Agora, o margin é removido e a color volta a ser o valor computado herdado.

Você também pode usar o valor unset com a propriedade all. Voltando ao exemplo acima, o que acontece se os estilos globais p obtiverem algumas propriedades adicionais? Apenas a regra que foi definida para margin e color será aplicada.

/* Estilos de cores globais para parágrafo em CSS autoral */
p {
    margin-top: 2em;
    color: goldenrod;
    padding: 2em;
    border: 1px solid;
}

/* Nem todas as propriedades são computadas */
aside p {
    margin: unset;
    color: unset;
}

Se você alterar a regra aside p para all: unset, não importa quais estilos globais serão aplicados a p no futuro, eles sempre serão unset.

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

Check your understanding

Teste seu conhecimento sobre herança

Quais das seguintes propriedades são herdáveis?

animation
Animações não passam para os filhos.
font-size
🎉
color
🎉
text-align
🎉
line-height
🎉

Qual valor se comporta como inherit e quando não há nada para herdar se comporta como initial?

reset
incorreto, tente novamente!
unset
🎉
superset
incorreto, tente novamente!

Referências