Herança CSS

visualizações (a contar de 13/11/2017) Publicado em: 14/03/2011 — Atualizado em: ➠ 26/04/2014 ➠ 13/11/2017

Introdução

Para se entender a herança CSS é necessário que se saiba o que é árvore do documento ou DOM (Document Object Model). O conceito de árvore do documento é melhor entendido quando fazemos uma analogia com a árvore genealógica de uma família, que é uma noção bem entendida pela maioria das pessoas.

Em uma família o relacionamento entre seus membros é expresso pelo grau de parentesco. Assim, temos indivíduos que são filhos, pais, avós, irmãos, primos, ancestrais, descendentes etc.

Um documento HTML pode ser representado pelo que chamamos de árvore do documento ou DOM representação essa que estabelece o relacionamento entre os elementos da marcação de maneira idêntica como se relacionam os membros de uma família. Existem elementos HTML pais, filhos, irmãos, ancestrais, descendentes, etc.

Considere um documento HTML com a seguinte marcação.

HTML

<!doctype html>
<html lang="pt-br">
<head>
	<title>Tutorial CSS - Herança CSS</title>
</head>
<body>
	<ul>
		<li>Item 1</li>
		<li>Item 2</li>
		<li>Item 3</li>
	</ul>
</body>
</html>

A árvore do documento criada pela marcação HTML mostrada, está representada no diagrama a seguir.

diagrama arvore documento

Observe a seguir alguns "graus de parentesco" entre os elementos HTML do documento representado no diagrama.

  • html é pai de head e body
  • ul é pai de três li
  • title é filho de head
  • Os três elementos li são irmãos
  • ul, body e html são ancestrais de li
  • title e ul são descendentes de html

Tal como ocorre em uma família quando um filho herda uma característica de seu pai ou avô, as propriedades CSS são também herdadas de seus ancestrais, pelos elementos HTML.

Herança

Considere a regra CSS mostrada a seguir, destinada a definir a cor do texto de um elemento p (parágrafo) que contém um elemento em (ênfase). Ou seja, o elemento em é filho do elemento p.

CSS

p {color: red;}

HTML

<p>Texto do parágrafo com um <em>elemento EM</em> nele contido.</p>

A renderização do parágrafo se dá como mostrado a seguir.

Texto do parágrafo com um elemento EM nele contido.

Notar que embora não tenhamos definido explicitamente uma cor para o elemento em ele foi renderizado na cor vermelha. Isso se deu devido a herança CSS. O que ocorreu foi que o elemento em herdou a propriedade color de seu elemento-pai p.

E, se quiséssemos que o elemento em fosse na cor azul? Nesse caso teríamos que anular o efeito da herança, definindo explicitamente a cor azul para em, como mostrado a seguir.

CSS

p {color: red;}
p em {color: blue;}

HTML

<p>Texto do parágrafo com um <em>elemento EM</em> nele contido.</p>

A renderização do parágrafo se dá como mostrado a seguir.

Texto do parágrafo com um elemento EM nele contido.

Mas, uma propriedade CSS não herda somente do seu elemento pai. Ela pode ser herdada de um elemento ancestral. O exemplo a seguir esclarece esse tipo de herança.

HTML

<div>
	<p>Texto do parágrafo com um <em>elemento EM</em> nele contido.</p>
</div>

A renderização do parágrafo se dá como mostrado a seguir.

Texto do parágrafo com um elemento EM nele contido.

Nesse exemplo a cor vermelha foi definida para o elemento div. O elemento em herdou a cor vermelha definida para seu elemento ancestral div. O elemento p, por ser elemento filho de div também herdou a cor.
Poderíamos dizer: "A cor passou de avô (div) para pai (p) e de pai para filho (em)".

Mas afinal, qual é a vantagem da herança CSS?

A grande vantagem da herança CSS é a redução drástica da quantidade de regras de estilos que teremos que escrever, diminuindo, e muito, o tamanho e tempo de carregamento da folha de estilos.

Um documento HTML sem uma folha de estilos a ele associada é estilizado conforme as regras CSS da folha de estilo nativa do navegador, que infelizmente varia de acordo com o navegador. Contudo algumas propriedades CSS são estilizadas nativamente de forma consistente por todos os navegadores, por exemplo, a cor dos textos é a preta, a família das fontes é a serif e o tamanho da fonte é igual a 16px.

Se não houvesse a herança teríamos que escrever uma regra CSS para cada elemento da página, pois aqueles não contemplados por regra CSS renderizariam de acordo com a folha de estilos nativa do navegador. Observe a regra CSS a seguir.

CSS

body { 
	color: red;
	font-family: arial, sans-serif;
}

O elemento body é ancestral de TODOS os elementos que renderizam em uma página web. Assim, eles herdarão do seu ancestral body a cor vermelha (red) e a fonte arial ou, alternativamente, sans-serif.

É claro que você não ficará preso à herança na sua página, pois como vimos anteriomente ao declarar uma regra CSS específica para um elemento da página ela sobrescreve (ou prevalece sobre) a herança.

Propriedades herdadas

Considere a folha de estilo e marcação HTML mostradas a seguir.

CSS

p {border:1px solid red;}

HTML

<p>Texto do parágrafo com um <em>elemento EM</em> nele contido.</p>

Aplicando os conceitos de herança estudados anteriormente é de se esperar que o elemento em por ser elemento filho de p receberá por herança uma borda vermelha, conforme mostrado a seguir.

Texto do parágrafo com um elemento EM nele contido.

Imagine um cenário considererando que o projeto de uma página prevê uma borda em torno de toda a página. Você ao criar a marcação HTML para a página define um elemento div container para a página e cria uma regra CSS na folha de estilos para adicionar àquele elemento div a borda prevista no projeto. TODOS os elementos da página herdariam a borda e você pode imaginar o caos que isso causaria no design e a quantidade de regras CSS para retirar as bordas uma a uma de todos os elementos descendentes daquele elemento div.

Felizmente, nem todas as propriedades CSS são herdáveis.

O cenário que foi imaginado anteriormente não acontece na prática pelo fato de que nem todas as propriedades CSS se transmitem por herança.

As seguintes propriedades CSS não são herdadas por elementos descendentes:

  • background
  • border (exceto: border-collapse e border-spacing)
  • clip
  • content
  • counter
  • clue
  • display
  • float
  • height
  • left
  • margin
  • outline
  • overflow
  • padding
  • page-break
  • pause
  • play-during
  • position
  • right
  • table-layout
  • text-decoration
  • top
  • unicode-bidi
  • vertical-align
  • width
  • z-index

Como você pode constatar na listagem mostrada a propriedade border não é herdada. Assim, o exemplo mostrado no cenário anterior não acontece na prática, pois o elemento em não herdará a borda definida para seu elemento ancestral div.

Herança para a propriedade font-size

A herança funciona para a propriedade font-size? Sim funciona, isto é a propriedade font-size é herdável, mas o valor a ser herdado depende da unidade de medida CSS usada para se definir o valor declarado para o elemento ancestral.

Valores relativos são calculados em relação a um valor tomado como base. Assim, se o valor do tamanho da fonte para um elemento for definido em porcentagem, em unidade CSS em ou em qualquer valor relativo o valor a ser herdado pelos seus elementos descendentes não é valor declarado para o elemento ancestral e sim o valor calculado para a unidade de medida relativa declarada.

O exemplo mostrado a seguir esclarece a herança para esses casos.

CSS

p {font-size: 150%;}

HTML

<p>Texto do parágrafo com um <em>elemento EM</em> nele contido.</p>

O tamanho da fonte para o elemento p foi de 150% (valor declarado para o elemento ancestral). Mas, 150% de quê? Unidade de medida CSS expressa em porcentagem se refere à medida definida para o elemento pai ou se não houver um elemento pai, para o elemento ancestral mais próximo. Assim font-size: 150% significa um tamanho de fonte igual a 1,5 vezes o tamanho da fonte do elemento ancestral mais próximo do elemento p.

Não havendo elemento ancestral com tamanho de fonte declarado toma-se o tamanho de fonte padrão do elemento body que é o ancestral mais distante e por padrão, nos navegadores, esse tamanho é igual a 16px. Esse é o caso do nosso exemplo.

Assim, no nosso exemplo, o tamanho de fonte para o parágrafo será de 16px x 1,5 = 24px (valor calculado). Como o elemento em é elemento filho do elemento p, ele herda a propriedade font-size e seu tamanho de fonte será 150% x 24px = 36px. Nessas condições obteríamos uma renderização como mostrado a seguir.

Texto do parágrafo com um elemento EM nele contido.

Esse é o comportamento da herança se considerarmos o que foi mostrado nos itens anteriores desse tutorial. Contudo não é isso que acontece quando se trata da propriedade font-size.

O valor herdado pelos elementos descendentes é igual ao valor calculado para o elemento ancestral, ou seja 24px, como mostrado no exemplo a seguir.

Texto do parágrafo com um elemento EM nele contido.

Notar que o tamanho de fonte do elemento filho em é o mesmo do restante do elemento p. Isso porque, como dissemos, para unidades relativas, tamanho de fonte herdado é o valor calculado (24px) e não o valor declarado (150%), e nesse caso o valor calculado foi 24px.

Interferindo na herança CSS

Existem três palavras-chave para serem usadas como valor para propriedades CSS, cujo significado é essencial que se conheça, pois eles interferem com a herança CSS.

Essas palavras-chave são listadas e seus efeitos definidos a seguir.

  • inherit — esse valor destina-se a definir explicitamente que o valor da propriedade deve ser herdado.
  • initial — esse valor destina-se a definir explicitamente que o valor da propriedade para a qual foi definida deve ser igual ao valor definido para seu elemento antecessor pela folha de estilos padrão do navegador. Se nenhum valor for definido pela folha de estilos padrão do navegador e a propriedade for herdável, o valor da propriedade será herdado.
  • unset — esse valor destina-se a redefinir a propriedade para seu valor natural, o que significa que se a propriedade é naturalmente herdada age como herdada, caso contrário ela age como inicial.

O exemplo mostrado a seguir esclarece os efeitos desses valores na herança CSS.

CSS

.container { /* elemento pai */
	color: red; /* a cor passa por herança */
	border: 1px solid blue;  /* a borda não passa por herança */
}
.inherit {color: inherit; border: inherit;} /* elemento filho 2o. parágrafo */ 
.initial {color: initial; border: initial;} /* elemento filho 3o. parágrafo */ 
.unset {color: unset; border: unset;} /* elemento filho 4o. parágrafo */ 

HTML

<div class="container">
	<p>Texto do 1o. parágrafo sem classe definida.</p>
	<p class="inherit">Texto do 2o. parágrafo com classe inherit.</p>
	<p class="initial">Texto do 3o. parágrafo com classe initial.</p>
	<p class="unset">Texto do 4o. parágrafo com classe unset.</p>
</div>

A estilização dos parágrafos é como mostrada a seguir

Texto do 1o. parágrafo sem classe definida.

Texto do 2o. parágrafo com classe inherit.

Texto do 3o. parágrafo com classe initial.

Texto do 4o. parágrafo com classe unset.

Para o primeiro parágrafo a cor vermelha do texto foi herdada do seu elemento pai e a borda azul não foi herdada, segundo as regras padrão para herança CSS.
Para o segundo parágrafo (inherit) a cor vermelha do texto foi herdada do seu elemento pai de maneira "explícita" e a borda azul também foi herdada de maneira "explícita".
Para o terceiro parágrafo (initial) tanto a cor vermelha do texto como a borda azul não foram herdadas do seu elemento pai, pois a folha de estilo padrão do navegador define a cor inicial de textos sendo a preta e o valor inicial de bordas sendo none.
Para o quarto parágrafo (unset) a cor vermelha do texto foi herdada do seu elemento pai conforme o padrão para herança de cor e a borda azul não foi herdada do seu elemento pai conforme o padrão para herança de bordas.

Conclusão

É assim que funciona (ou deixa de funcionar) a herança CSS. Antes do desenvolvimento de suas folhas de estilo faça um estudo do seu projeto e tire o máximo proveito da herança CSS.

topo