Também disponível em: English · Español · Français · العربية
Calculadora de especificidade CSS
A especificidade de qualquer seletor como os três números que a cascata compara de facto, com cada parte justificada e a resposta do atalho ao lado da verdadeira.
O que é a especificidade em CSS?
Quando duas regras CSS se aplicam ao mesmo elemento e mexem na mesma propriedade, é a especificidade que decide qual ganha. Calcula-se só a partir do seletor — não de onde a regra está, nem do ar complicado que tenha — e a especificação de seletores define-a como três contagens, não como um número.
A primeira, A, é o número de seletores de id. A segunda, B, conta em conjunto os seletores de classe, os de atributo e as pseudoclasses — um seletor de atributo pesa exatamente o mesmo que uma classe. A terceira, C, conta os seletores de etiqueta e os pseudoelementos. O seletor universal não conta nada.
Cole um seletor acima e obtém esses três números, mais uma linha por cada parte a explicar em que coluna caiu e porquê. Se puser um segundo seletor, diz-lhe qual dos dois ganharia.
Como usar
- Escreva ou cole um seletor. De div até #nav .item:not(.disabled)::before. Listas de seletores separadas por vírgulas também funcionam, e cada entrada é contada por si.
- Leia as contas, não só o total. Cada seletor simples tem a sua própria linha a dizer em que coluna contou e porquê, portanto um total surpreendente fica explicado em vez de apenas afirmado.
- Acrescente um segundo seletor para comparar. Obtém o vencedor e, ao lado, a pontuação em base 10 — com um aviso nas ocasiões em que esse atalho aponta ao contrário.
Porque onze classes não ganham a um id
Quase toda a gente aprende a especificidade como aritmética: um id vale 100, uma classe 10, uma etiqueta 1, soma-se e ganha o número maior. É uma mentira útil que funciona para quase todos os seletores que alguém escreve, e depois deixa de funcionar sem aviso.
A especificação é explícita: os três números são comparados coluna a coluna. Ganha quem tiver o A maior, e só se os A empatarem é que se olha para o B, e só então para o C. Não há transporte, nem total, nem taxa de câmbio. Um id ganha a qualquer quantidade de classes — a cem, a mil.
Onze é onde o atalho começa a mentir, e isso não é palpite. Onze classes pontuam 110 contra os 100 de um id, portanto a aritmética diz que ganham as classes enquanto a cascata diz que ganha o id. Dez classes ainda pontuam 100, um empate que o atalho resolve como a regra verdadeira por mero acaso. A ferramenta vem com exatamente esse par carregado para que veja os dois modelos a discordar em vez de acreditar.
E também não é um caso hipotético. Uma folha de estilos de utilitários empilha classes no mesmo elemento como coisa normal, e a especificação nota que repetir um seletor simples aumenta mesmo a especificidade: .btn.btn.btn é 0-3-0. Onze fica mais perto do que parece.
As partes que apanham as pessoas
Quatro pseudoclasses têm regras próprias, e é aí que as contas à mão correm mal. :is(), :not() e :has() não se contam a si mesmas — cada uma toma a especificidade do seletor mais específico que leva dentro, portanto :not(#a) vale um id inteiro. :where() é o contrário e é a útil: é substituída por zero, de modo que tudo lá dentro não contribui com nada por mais específico que pareça, e é isso que faz dela a ferramenta certa para estilos por omissão que quer que sejam fáceis de sobrepor.
:nth-child() e :nth-last-child() são o par obscuro. Contam como uma pseudoclasse por si e depois somam o seletor mais específico de uma cláusula of, se existir — portanto :nth-child(2n of .item) é 0-2-0 e não 0-1-0.
Depois há uma armadilha puramente histórica. :before, :after, :first-line e :first-letter são pseudoelementos escritos com dois pontos simples, permitido por compatibilidade com o CSS2. O sinal simples faz com que pareçam pseudoclasses, e ainda assim contam na terceira coluna com as etiquetas. Qualquer outro nome com dois pontos simples é mesmo uma pseudoclasse e conta na segunda.
Limites honestos
A especificidade é só um passo da cascata, e esta página calcula esse passo e mais nada. Antes dela vêm a origem e a importância — uma declaração com !important ganha a uma normal digam o que disserem os seletores, e as camadas de cascata também são vistas antes da especificidade. Os estilos em linha ficam fora do terno do seletor, e não há seletor que possa escrever que os ultrapasse. Depois da especificidade, se duas regras continuarem empatadas, ganha a que vier mais tarde no código — que é o que aqui significa o resultado de empate.
O cálculo assume também que o seletor é válido. Isto lê o que escreve sem verificar se um navegador o aceitaria, portanto uma gralha é contada em vez de recusada, e pseudoclasses com prefixo de fabricante ou acabadas de propor são tratadas como correntes a não ser que estejam entre os casos especiais acima.
Mais uma coisa que vale a pena saber: a especificação permite que as implementações limitem os três valores se ficarem sem espaço, portanto um seletor absurdo pode acabar travado num navegador a sério em vez de contado com exatidão. Nada do que escreva à mão chega perto.
Os números aqui foram verificados contra os catorze exemplos resolvidos da própria especificação e, à parte, contra uma implementação de referência sobre 980 seletores gerados, sem uma única divergência.
Porque é grátis
Porque não custa nada manter. A análise e a contagem acontecem no seu navegador; nenhum seletor é enviado, nenhum servidor vê a sua folha de estilos e não há conta nenhuma.
As regras saem da especificação de seletores do CSS e não de um tutorial, e os testes que as verificam estão guardados ao lado do código — incluindo os exemplos da própria especificação, que é uma fasquia mais alta do que concordar com outra calculadora.