Entendendo especificidade no CSS na prática
O que é especificidade, afinal?
Especificidade é o sistema de pontuação que o navegador usa para decidir qual regra CSS se aplica quando há conflito entre seletores. Todo seletor recebe um peso: IDs valem mais que classes, classes valem mais que elementos, e a tag html tem um peso base mínimo. O browser some tudo isso e escolhe a regra com maior pontuação. Muita gente acha que é só memorizar uma tabela. Não é. A coisa funciona de verdade como um contador de tripla base: (inline styles, IDs, classes + pseudo-classes), (pseudo-elementos, atributos), (elementos). Quando dois seletores empatam, vence o que veio depois no código. Ponto.
Aqui vai um detalhe que ninguém enfatiza direito: especificidade não é poder. Ela é apenas desempate. Se você está brigando contra ela, seu problema é estrutura, não conhecimento de CSS.
Como eu lido com isso no dia a dia
Eu comecei a escrever CSS em 2008, quando o IE6 era o pesadelo de todo mundo. Aprendi especificidade na marra, com layouts quebrados porque um !important aparecia em algum arquivo que eu não tinha editado. Hoje eu uso uma abordagem bem simples: escrevo seletores planos, evito IDs em estilos, e confio na cascata. Se você quer um guia rápido:
- Use classes para estilização, não IDs
- Evite aninhamento profundo — cada nível extra aumenta o peso sem benefício real
- Sempre verifique o arquivo de ordem de carregamento quando algo não sobrescreve como deveria
- Firefox DevTools mostra a hierarquia de especificidade visualmente. Use isso antes de perguntar em fórum
Um caso real que me deu trabalho
Num projeto interno, eu tinha um componente de card com uma classe .card__title. Por algum motivo, o título sempre puxava o estilo do seletor global h2, mesmo eu tendo definido .card__title com tamanho maior. Passei uns 40 minutos tentando descobrir o problema. A causa era um seletor dentro de uma folha de reset que eu não tinha notado: h2.card__title. Isso vinha com uma especificidade de (0,1,1) — mais alta que minha classe simples (0,1,0). A solução foi apenas adicionar outra classe ao seletor, virando .card .card__title, ou usar o seletor direto no arquivo do componente.
👉 Clique no botão abaixo para saber mais sobre o assunto!
O trabalho extra foi principalmente de debug, não de compreensão teórica. O CSS estava certo. Eu é que não estava olhando para o lugar certo.
Insights que parecem contraintuitivos
1. Especificidade zero não existe. Até o seletor universal * tem peso, mas ele é (0,0,0). O problema é que qualquer coisa acima disso já vence. Então se você tem uma regra com * e outra com span, a do span ganha mesmo sendo mais genérica. A ordem importa. 2. !important é um atalho que vira armadilha. Ele existe. Mas uma vez que você começa a usá-lo em vários lugares, a manutenibilidade cai junto. Em projetos grandes, eu já vi arquivos com dezenas de !importantes espalhados, e aí ninguém mais sabe qual regra realmente vence. É mais rápido refatorar os seletores do que gerenciar esses conflitos.
3. O seletor :is() e :where() foram criados justamente para resolver parte desses problemas. :where() tem especificidade zero, então você pode empilhar quantos seletores quiser sem aumentar o peso. :is() herda a especificidade do seu argumento mais pesado. Eu uso :where() para resets e normalizações, e :is() quando preciso agrupar variantes com peso previsível.
Limitações e quando isso não resolve
Especificidade sozinha não resolve layout quebrado. Se um componente está com o tamanho errado, o problema pode ser display, box-sizing, ou até uma regra de herança que você esqueceu. CSS é muito mais amplo que pontuação de seletores. Em sistemas com muitas bibliotecas third-party, como componentes React ou Web Components, a especificidade pode se tornar imprevisível se cada biblioteca usa estratégias diferentes. Nesse cenário, a melhor alternativa é isolar o escopo com CSS Modules, Shadow DOM, ou namespacing rigoroso. Não adianta tentar lutar contra a cascata nesses casos.
Resumo rápido sem rodeio
Especificidade é um sistema de priorização baseado em tipos de seletores. IDs vencem classes, classes vencem elementos, e em empate vence o último declarado. A maioria dos problemas reais de CSS não é sobre forgetting a tabela de pesos, é sobre não olhar o código certo no momento errado. Use ferramentas de debug, evite !important como muleta, e pense em estrutura antes de pensar em pontuação. Se você quer se aprofundar, a MDN tem uma página técnica bem completa, e o artigo do Stephanie Eckles sobre especificidade em projetos reais também vale a leitura. Nada de guruismos — só prática acumulada.