FreeToGenerate.com

Os id valem 100 e as classes 10, portanto onze classes ganham a um id? Não ganham — e onze é exatamente onde esse atalho começa a mentir.

0-11-0

Como cada parte foi contada

  • .btnBUm seletor de classe, contado na segunda coluna.
  • .btn-primaryBUm seletor de classe, contado na segunda coluna.
  • .is-activeBUm seletor de classe, contado na segunda coluna.
  • .is-largeBUm seletor de classe, contado na segunda coluna.
  • .has-iconBUm seletor de classe, contado na segunda coluna.
  • .is-roundedBUm seletor de classe, contado na segunda coluna.
  • .is-blockBUm seletor de classe, contado na segunda coluna.
  • .is-loadingBUm seletor de classe, contado na segunda coluna.
  • .is-disabledBUm seletor de classe, contado na segunda coluna.
  • .is-focusBUm seletor de classe, contado na segunda coluna.
  • .is-hoverBUm seletor de classe, contado na segunda coluna.
A
A — identificadores
B
B — classes, atributos e pseudoclasses
C
C — etiquetas e pseudoelementos

Qual ganha

0-11-0vs1-0-0

Ganha o segundo seletor

A pontuação em base 10 que toda a gente aprende

Pontuação: 110 vs 100

O atalho engana-se aqui. A especificidade são três números comparados coluna a coluna, e não um total — por isso nenhuma quantidade de classes vence alguma vez um id, por mais alta que a pontuação fique.

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

  1. 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.
  2. 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.
  3. 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.