DevPath · Aprenda a programar ESPTEN

CSS: seletores, cascata e especificidade

Especificidade e !important

O que é a especificidade?

Aqui está a outra metade do mistério "por que meu CSS não se aplica?". Quando duas regras de mesma origem colidem, não vence a última pura e simplesmente: vence a de maior especificidade, uma medida do peso do seletor. Ela é calculada contando três categorias, que você pode imaginar como um número de três colunas (A, B, C):

Categoria Conta Peso
id (#cabecalho) nº de ids 100
classe / atributo / pseudo-classe (.aviso, [type], :hover) nº deles 10
elemento / pseudo-elemento (div, ::before) nº deles 1

O seletor universal * e os combinadores ( , >, +, ~) não contribuem com especificidade.

Exemplos comparados

/* especificidade 0,0,1  → 1 */
p { color: black; }

/* especificidade 0,1,1  → 11 */
p.destacado { color: green; }

/* especificidade 0,1,0  → 10 */
.destacado { color: blue; }

/* especificidade 1,0,0  → 100 */
#aviso { color: red; }

Sobre um <p class="destacado" id="aviso">, venceria #aviso (100) porque o id pesa mais que qualquer combinação de classes ou elementos. E entre p.destacado (11) e .destacado (10), vence p.destacado por ser mais específico, ainda que .destacado seja declarado depois.

A comparação é categoria a categoria, da esquerda para a direita: um único id vence qualquer número de classes, e uma única classe vence qualquer número de elementos. Por isso 10 classes (0,10,0) não superam um id (1,0,0).

⚠️ CILADA CLÁSSICA: id passa por cima de classe, e classe passa por cima de tag, não importa a ordem. Imagine um menu com .link { color: gray } para o estado normal e #menu a { color: tomato } para destacar: o id manda e os links saem laranja, mesmo a classe estando escrita depois. Não é mágica nem falha do navegador; é a coluna da esquerda mandando sobre a da direita. Quando uma regra "não funciona", a primeira coisa a se perguntar é qual outra a está superando em especificidade.

!important: o último recurso

Adicionar !important a uma declaração a tira da competição normal de especificidade e a coloca acima:

.botao { color: blue !important; }
#cabecalho .botao { color: red; }   /* perde: o !important vence */

Funciona, e é justamente por isso que vicia: quando algo "não se aplica", jogar um !important resolve na hora. O problema é que é solução de curto prazo que cobra caro depois, uma má prática, exceto em casos muito pontuais:

A boa prática é manter a especificidade baixa e uniforme (apoie-se em classes, evite os ids para estilizar e não aninhe seletores em excesso). Assim a cascata e a ordem de aparição bastam para que a regra correta vença, e o !important fica onde deve: como último recurso, não como seu martelo para tudo.

Coloque isto em prática

O DevPath é um curso prático: aqui você lê a teoria; no app você a coloca em prática com exercícios que rodam de verdade, offline.

Comece grátis no app →
← A cascata e a herançaVer o módulo →