A especificidade e o efeito cascata

Publicado em: 25/02/2004 | Atualizado em: 06/06/2014

Introdução

Neste Tutorial vou abordar a especificidade das regras CSS, que se for esquecida, desconhecida ou negligenciada, acaba por trazer sérias dores de cabeça quando se constata que "alguma coisa não está funcionando como era de se esperar".

Algo como: Por que este parágrafo que era para ser visualizado na cor vermelha, está verde? Você examina suas folhas de estilo e lá está claramente declarado p { color: #f00; }. Verifica que esta regra é a última que você escreveu naquela Folha de Estilo e esta por sua vez também é a última a ser importada e/ou linkada no documento. Também vai ao código HTML e não há um estilo inline declarado no parágrafo. Aí você conclui que pelo "efeito cascata" não há por que aquele parágrafo estar na cor verde. Não há lógica! Mas, o que há de errado! De repente você se lembra de um detalhe e apressa-se a limpar o cachê do navegador. Sim, deve ser isso! Mas, mesmo assim o parágrafo insiste em continuar na cor verde.

O efeito cascata

O uso das folhas de estilo para controlar o "visual" de um documento HTML, não raro resulta em regras CSS distintas, aplicáveis a um mesmo elemento no documento. Ou seja, fica estabelecido um conflito entre regras. Qual delas, regra, prevalece? Ah , isso você já sabe, entra aqui o conhecido "Efeito Cascata". Não lembra? Leia o último parágrafo do tutorial intitulado Introdução às CSS.

A especificidade

A especificidade da regra CSS as vezes nos reserva "surpresas". Você deve conhecer como funciona a especificidade para evitar as surpresas.

E vamos a um exemplo ilustrativo que certamente irá tornar mais claro este conceito do que um extenso parágrafo explicativo.

Observe o trecho de documento HTML abaixo

body {
font-family: verdana, arial, helvetica, sans-serif;
font-size: 9px;
}
#conteudo p.nivelc {
color: #0f0; /* Cor verde */
} 
#conteudo p {
color: #00f; /* Cor azul */
font-size: 18px;
} 
p {
color: #f00; /* Cor vermelha */
font-size: 26px;
} 
<div id="conteudo">
    <p class="nivelc">
    Texto do primeiro parágrafo, blá...blá..
    </p>

    <p> 
    Texto do segundo parágrafo, blá...blá...
    </p>

</div>

<p> 
Texto do terceiro parágrafo, blá...blá...
</p>

</body>
</html>

O documento é rederizado e apresentado na tela como mostrado abaixo.

Tres textos em tamanhos e cores diferentes

Note que foram declaradas 03 (três) regras CSS, todas elas, aplicáveis ao elemento p.

  • o primeiro parágrafo está dentro da div conteudo e lhe foi atribuida a classe nivelc;
  • o segundo parágrafo está dentro da div conteudo;
  • o terceiro parágrafo está fora da div conteudo dentro da tag <body>

Diz-se que para aplicação no parágrafo, o seletor #conteudo p.nivelc é mais específico que p.nivelc que por sua vez é mais específico que p

Mas, isto tudo parece bastante óbvio não é? Sim concordo, no entanto este exemplo visa somente a recordar o que seja especificidade. Imagine uma complexa e extensa Folha de Estilo, com várias regras aplicavéis a um mesmo elemento.

Guardemos por enquanto o conceito de especificidade como sendo "O nível de detalhamento do seletor da regra CSS".

Lembro a sintaxe de uma regra CSS:
seletor { propriedade: valor; }
Nota: é o seletor que determina a especificidade da regra.

A declaração CSS com !important

Uma declaração CSS pode ser declarada importante conforme a sintaxe geral mostrada a seguir:

seletor { propriedade: valor !important }

A declaração com uso de !important como mostrada, faz com que para aquela declaração o seletor tenha prioridade sobre todos os demais seletores iguais a ele, independentemente da especificidade e do efeito cascata.

Havendo conflito entre regras CSS !important, declaradas pelo autor do documento e pelo usuário, prevalecem as regras do usuário.

Um usuário com restrições de visão, por exemplo, poderá ter declarado para seu navegador estilo !important, para fontes de tamanho grande. Se o autor do documento, inseriu !important na declaração de suas fontes, não impossibilitará aquele usuário a leitura de sua página web por ter projetado uma fonte menor e a declarado !important.

Calculando a especificidade das regras CSS. 

Conforme vimos, o que determina a especificidade da regra CSS é o seu seletor.

Havendo conflito, não definido pelo efeito cascata, ou declaração !important, a prioridade será definida pela especificidade.

A maneira prática de calcular qual das regras conflitantes prevalecerá, baseado na especificidade, consiste em se atribuir, segundo o critério mostrado a seguir, uma pontuação para os seletores das regras conflitantes. Prevalecerá aquela cujo seletor obtenha a maior pontuação.

CÁLCULOS:
1°.-) Conte o número (quantidade) 
de atributos id no seletor;
2°.-) Conte o número (quantidade)
 de atributos classe no seletor;
3°.-) Conte o número (quantidade) 
de tag's HTML no seletor;
4°.-) Escreva os números obtidos, 
da esquerda para a direitae na mesma
ordem em que foram levantados (id,classe,tag). 
O número assim obtido é a 
pontuação da especificidade da regra.

Exemplos:
1-) Nesta regra #conteudo p.nivelc {... 
temos-->uma id, uma classe e uma tag HTML
    
2-) Nesta regra p span.nivelc {...
temos--> zero id, uma classe e duas tag's HTML

Pontuação da primeira regra = 111
Pontuação da segunda regra = 012

Havendo empate na pontuação vale o efeito cascata. 
A última regra declarada prevalece.
Cálculo da pontuação para especificidade
Seletor ID's Classes Tag's Pontuação
strong 0 0 1 001
p strong 0 0 2 002
.nivelc 0 1 0 010
a:hover 0 1 1 011
div h1.niveld 0 1 2 012
#conteudo p 1 0 1 101
#conteudo 1 0 0 100

Um exemplo bastante comum, onde ocorre a aplicação da especificidade na prática é nas Folhas de Estilo para construção de menus com listas, onde usualmente são declaradas regras do tipo: #menu, #menu ul, #menu ul li, #menu li a, etc...etc...

Conclusão

Não esqueça de "checar" suas regras conflitantes pelo critério de especificidade, quando aparecer um problema do tipo "Esta tag não está de acordo com as regras que eu escrevi! Já revisei tudo e não encontro o erro, o que está havendo?"

X

Matérias recomendadas

A sintaxe da regra CSS

Seletores CSS3