Herança

Podcast do CSS - 005: herança

Digamos que você acabou de criar CSS para fazer os elementos parecerem um botão.

<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;
}

Em seguida, você adiciona um elemento de link a um artigo de conteúdo, com um valor class de .my-button. No entanto, há um problema, o texto não tem a cor que você esperava. Como isso aconteceu?

Se você não especificar um valor para algumas propriedades CSS, elas serão herdadas. No caso desse botão, ele herdou o color do CSS:

article a {
  color: maroon;
}

Nesta aula, você vai aprender por que isso acontece e como a herança é um recurso poderoso para ajudar você a escrever menos CSS.

Fluxo de herança

Vamos conferir como funciona a herança. usando este snippet 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 no documento. Adicione CSS ao elemento HTML e ela começa a se propagar em cascata.

html {
  color: lightslategray;
}

A propriedade color é herdada por padrão 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;
}

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

Quais propriedades são herdadas por padrão?

Nem todas as propriedades CSS são herdadas por padrão. mas há muitos que são. Como referência, aqui está a lista inteira de propriedades que são herdadas por padrão retirado da referência W3 de todas as propriedades CSS:

Como funciona a herança

Todo elemento HTML tem todas as propriedades CSS definidas por padrão com um valor inicial. O valor inicial é uma propriedade que não é herdada e aparece como padrão se a cascata não calcular um valor para esse elemento.

As propriedades que podem ser herdadas descem em cascata e os elementos filhos receberão um valor calculado que representa o valor do pai. Isso significa que, se um pai tiver font-weight definido como bold, todos os elementos filhos estarão em negrito, a menos que o font-weight esteja definido com um valor diferente, ou a folha de estilo do user agent tenha um valor font-weight para esse elemento.

Como herdar e controlar explicitamente a herança

A herança pode afetar elementos de maneiras inesperadas, por isso o CSS tem ferramentas para ajudar com isso.

A palavra-chave inherit

É possível fazer qualquer propriedade herdar o valor calculado do pai com a palavra-chave inherit. Uma maneira útil de usar essa palavra-chave é criar exceções.

strong {
  font-weight: 900;
}

Este snippet de CSS define todos os elementos <strong> com font-weight de 900. em vez do valor padrão bold, que seria o equivalente de font-weight: 700.

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

A classe .my-component define font-weight como 500. Para fazer com que os elementos <strong> dentro de .my-component também font-weight: 500 adicionem:

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

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

É possível definir explicitamente esse valor, mas se você usar inherit e o CSS de .my-component mudar no futuro, você pode garantir que o dispositivo <strong> será atualizado automaticamente.

A palavra-chave initial

A herança pode causar problemas com seus elementos, e o initial oferece uma opção de redefinição eficiente.

Você já aprendeu que cada propriedade tem um valor padrão no CSS. A palavra-chave initial define uma propriedade de volta para esse valor inicial padrão.

aside strong {
  font-weight: initial;
}

Esse snippet remove a espessura em negrito de todos os elementos <strong> dentro de um elemento <aside>. Em vez disso, torná-los peso normal, que é o valor inicial.

A palavra-chave unset

A propriedade unset se comportará de maneira diferente se uma propriedade for herdada por padrão ou não. Se uma propriedade for herdada por padrão, a palavra-chave unset será igual a inherit. Se a propriedade não for herdada por padrão, a palavra-chave unset será igual a initial.

Lembrar quais propriedades do CSS são herdadas por padrão pode ser difícil, unset pode ser útil nesse contexto. Por exemplo, color é herdado por padrão, mas margin não, então você pode escrever isto:

/* 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;
}

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

Também é possível usar o valor unset com a propriedade all. Voltando ao exemplo acima, o que acontece se os estilos p globais receberem mais algumas propriedades? Somente a regra que foi definida para margin e color será aplicada.

/* 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;
}

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

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

Teste seu conhecimento

Teste seus conhecimentos sobre herança

Quais das seguintes propriedades são herdáveis?

animation
As animações não são transmitidas para filhos.
font-size
🎉
color
🎉
text-align
🎉
line-height
🎉

Qual valor se comporta como inherit, a menos que não haja nada para herdar e se comporta como initial?

reset
não é um valor válido, tente novamente.
unset
🎉
superset
não é um valor válido, tente novamente.

Recursos