A guerra da especificidade CSS

Introdução

Junte-se a mim e governaremos a galáxia como pai e geeks!

Há algumas semanas atrás na cidade de Cupertino eu assisti uma explicação dada pela Molly e o Aaron sobre como calcular a especificidade de seletores CSS usando um método que eu não havia visto antes. Hoje, ao desenvolver um template baseado em XHTML e CSS eu me deparei com um problema que me deu um nó em relação ao comportamento de dois seletores que não funcionaram como eu esperava e então cheguei a conclusão que meu treinamento não estava completo.

O lado negro da força

Meu problema era simples, servir uma imagem com transparência PNG para navegadores que entendem esta transparência e uma imagem GIF para navegadores antigos e que não entendem a transparência PNG sem recorrer a hacks.
A seguir o código de marcação:

CSS
<div id="nav-supp">
  <p><a id="a-02" href="#webstandards-org">Top</a></p>
  <!-- etc. -->
</div>

e a CSS pertinente:

CSS
a#a-02 { 
  background-image: url(n.gif); 
}
  a[id="a-02"] { 
  background-image: url(n.png); 
}

Eu acreditava que um navegador moderno seria capaz de entender e aplicar ambas as regras (sendo que a segunda regra prevaleceria sobre a primeira) e que um navegador antigo por não entender seletores de atributos, ignoraria a segunda regra e aplicaria a primeira. Eu estava errado. Navegadores modernos não aplicam a imagem PNG como eu esperava. O motivo disto? Um seletor simples do tipo id tem prioridade sobre um seletor de atributo em termos de efeito cascata. Caramba! Eu tenho consciência de que li as especificações, mas este detalhe particular escapou para mim. Se eu tivesse tido mais atenção teria aprendido que;

Seletores do tipo ID tem uma especificidade maior que seletores de atributos. Por exemplo, em HTML, o seletor #p123 é mais específico do que [id=p123] em termos de efeito cascata.

Lords Sith

Dando uma passada pelo Google descobriremos algumas leituras áridas sobre o assunto especificidade (ver mais no título "Links relacionados" no final deeste tutorial).

Em primeiro vamos dar uma olhada no que o Lord Elasticus (Patrick Griffiths) escreveu sobre o assunto especificidade (introduzindo uma ou duas modificações para servir aos nossos propósitos mais abomináveis).

Atribua a cada seletor id ("#whatever") um valor igual a 100, a cada seletor do tipo classe (".whatever") um valor igual a 10 e a cada seletor HTML (NT: Um seletor HTML é simplesmente um elemento HTML, como por exemplo p, h1, div, a etc. - seletor de elemento) ("whatever") um valor igual a 1. A seguir faça a soma de todos os valores e você obterá o valor da especificidade.

  • p tem uma especificidade igual a 1 ( seletor HTML 1)
  • div p tem uma especificidade igual a 2
    (2 seletores HTML; 1+1)
  • .sith tem uma especificidade igual a 10 (1 seletor de classe)
  • div p.sith tem uma especificidade igual a 12
    (2 selectores HTML e um seletor de classe; 1+1+10)
  • #sith tem uma especificidade igual a 100 (1 seletor tipo id)
  • body #darkside .sith p tem uma especificidade igual a 112 (seletor HTML, seletor id, seletor de classe, seletor HTML; 1+100+10+1)

Se todos os seletores mostrados acima forem usados em uma folha de estilos, o seletor div p.sith (com um valor de especificidade igual a 12) prevaleceria sobre o seletor div p (com um valor de especificidade igual a 2) e o seletor body #darkside .sith p prevaleceria sobre todos os demais independentemente da ordem em que os seletores tiverem sido escritos na folha de estilos.

Darth (Gez) Lemon quotes o W3C.

A Especificidade de um seletor é calculada como mostrado a seguir:

  • conte a quantidade de atributos ID no seletor (= a)
  • conte a quantidade de outros atributos e de pseudo classes no seletor (= b)
  • conte a quantidade de elementos no seletor (= c)
  • ignore os pseudo-elementos.

Concatenando os três números acima obtidos a-b-c (num sistema númerico em base elevada) obtém-se o valor da especificidade.

Complicou! Para mim, o W3C encontra-se em uma galáxia distante, muito distante!

É possível entender estes poderes?

Matemática nunca foi o meu forte, assim para facilitar meu entendimento no cálculo da especificidade eu construi uma carta baseada nos valores de especificidade (ou Sith power) como mostrado a seguir (Ed disse: Desconsidere estilos inline e declaração !important).


seletor de elemento

seletor de classe

seletor id
Sith power (especificidade): 0, 0, 1
(1)
Sith power (especificidade): 0, 1, 0
(10)
Sith power (especificidade): 1, 0, 0
(100)

A cada caractere (seletor) é atribuido seu próprio Sith power (valor de especificidade) dependendo de quão poderosos eles sejam nos caminhos do Lado Negro da Força. Uma tropa do deserto é menos poderosa que Vader que por sua vez é menos poderoso que o Imperador.

CSS: Specificity Wars
CSS: Guerra da Especificidade (jpg, 142Kb)
(Atualizado. Obrigado Molly e Eric pelo esclarecimento).

NT: Clique na figura para visualizar uma versão ampliada.

Links relacionados
(abrem em nova janela)

Não substime o poder do lado negro da força.

Divirta-se, Guerra nas Estrelas ajudou-me a entender melhor CSS. Junte-se a mim e governaremos a galáxia como pai e geeks!

Compartilhe essa matéria com seus amigos

logo twitter logo facebook logo linkedin logo reddit

Conheça os livros do Maujor®

Ir para a página de entrada nos sites dos livros.