Entendendo a Prioridade e a Especificidade dos Estilos CSS

No desenvolvimento web, é comum que múltiplos estilos CSS tentem influenciar a aparência de um mesmo elemento. Para resolver esses conflitos e determinar qual regra será aplicada, os navegadores seguem um conjunto de princípios conhecidos como prioridade e especificidade. Dominar esses conceitos é fundamental para prever e controlar o comportamento visual das suas páginas.

Hierarquia de Seletores Simples

Quando diferentes tipos de seletores apontam para o mesmo atributo de um elemento, a decisão é tomada com base em uma hierarquia de "força". A ordem de prevalência, do mais potente para o menos potente (antes de considerar !important), é a seguinte:

  1. Estilos Inline: Definidos diretamente no atributo style de um elemento HTML.
  2. Seletores de ID: Referenciam elementos por seu atributo id (ex: #meuID).
  3. Seletores de Classe, Atributo e Pseudo-classe:
    • Classes (ex: .minhaClasse)
    • Atributos (ex: [type="text"])
    • Pseudo-clases (ex: :hover, :first-child)
  4. Seletores de Elemento e Pseudo-elemento:
    • Elementos HTML (ex: div, p)
    • Pseudo-elementos (ex: ::before, ::after)

Observe o exemplo abaixo. Mesmo com diversas regras, o estilo definido pelo seletor de ID prevalece sobre os demais:


<html lang="pt-BR">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Exemplo Prioridade Simples</title>
    <style>
        /* Seletor de ID: Mais específico */
        #elementoUnico {
            color: darkred;
        }
        /* Seletor de Classe: Menos específico que ID */
        .conteudoDestaque {
            color: dodgerblue;
        }
        /* Pseudo-classe: Especificidade igual à de classe */
        /* Supondo que <div id="elementoUnico"> é o primeiro filho do <body> */
        body > :first-child { 
            color: green;
        }
        /* Seletor de Elemento: Menos específico */
        div {
            color: gray;
        }
    </style>
</head>
<body>
    <div id="elementoUnico" class="conteudoDestaque">Texto de Exemplo Visual</div>
</body>
</html>

Neste caso, o texto "Texto de Exemplo Visual" será exibido na cor darkred, pois o seletor de ID possui a maior especificidade entre as regras aplicáveis diretamente ao elemento.

Cálculo de Especificidade para Seletores Compostos

Para seletores mais complexos, que combinam vários tipos de seletores, a especificidade é calculada usando um sistema de pontuação. Cada tipo de seletor contribui com um "peso" em três categorias (A, B, C):

  • A: Número de seletores de ID.
  • B: Número de seletores de classe, seletores de atributo e pseudo-classes.
  • C: Número de seletores de elemento (tag) e pseudo-elementos.

A comparação é feita na ordem A → B → C. O seletor com a maior pontuação em A vence. Se as pontuações em A forem iguais, compara-se B. Se B também for igual, compara-se C. Se todas as pontuações (A, B, C) forem idênticas, a regra que foi declarada por último no código CSS (ou mais próxima do elemento no DOM, no caso de inline styles) terá prioridade.

A Regra !important: Esta declaração é uma exceção ao fluxo normal de especificidade, conferindo a prioridade mais alta possível a uma propriedade específica. No entanto, seu uso deve ser moderado, pois pode dificultar a manutenção e a depuração do CSS.

Considere o seguinte exemplo de seletores compostos:


<html lang="pt-BR">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Exemplo Especificidade Composta</title>
    <style>
        /* Seletor 1: ID e Elemento (1,0,1) */
        #blocoPrincipal p {
            color: purple;
        }

        /* Seletor 2: Classe e Elemento (filho direto) (0,1,1) */
        .secaoInterna > p {
            color: darkorange;
        }

        /* Seletor 3: Dois Elementos (0,0,2) */
        div p {
            color: steelblue;
        }

        /* Seletor 4: Pseudo-classe e Elemento (0,1,1) */
        /* Supondo que <p> é o primeiro filho de <div#blocoPrincipal> */
        #blocoPrincipal :first-child { 
            color: forestgreen;
        }
        
        /* Seletor 5: Elemento simples (0,0,1) */
        p {
            color: darkgray;
        }
    </style>
</head>
<body>
    <div id="blocoPrincipal" class="secaoInterna">
        <p>Parágrafo Aninhado</p>
    </div>
</body>
</html>

Para o texto "Parágrafo Aninhado", os cálculos de especificidade são:

  • #blocoPrincipal p: (A=1, B=0, C=1)
  • .secaoInterna > p: (A=0, B=1, C=1)
  • div p: (A=0, B=0, C=2)
  • #blocoPrincipal :first-child: (A=1, B=1, C=0) -> Este seletor é ainda mais específico para o p dentro de #blocoPrincipal. Ele tem A=1 porque usa o ID e B=1 porque usa a pseudo-classe.
  • p: (A=0, B=0, C=1)

Analisando os resultados, #blocoPrincipal :first-child (1,1,0) é o mais específico e fará com que o texto fique forestgreen. Se este não estivesse presente, #blocoPrincipal p (1,0,1) seria o mais específico e a cor seria purple.

O Mito dos Pesos Decimais

É comum encontrar a explicação de que seletores de ID valem 100 pontos, classes 10 e elementos 1, e que a soma desses pontos determina a prioridade. No entanto, essa analogia é enganosa. O sistema de especificidade não é baseado em um cálculo decimal simples onde 11 classes (110 pontos) poderiam superar 1 ID (100 pontos). Na realidade, um ID sempre supera qualquer número de classes. O sistema é mais comparativo: um ID na categoria A sempre será "mais forte" do que qualquer número de seletores na categoria B ou C.

Ordem da Cascata e Fontes de Estilo

A prioridade também é determinada pela origem e pela ordem em que os estilos são declarados. A "cascata" do CSS define a seguinte hierarquia de fontes de estilo:

  1. Estilos !important do Autor/Usuário: Regras marcadas com !important (porém, um !important do usuário pode sobrepor um do autor).
  2. Estilos Inline: Definidos diretamente no HTML.
  3. Estilos do Autor: Incluem folhas de estilo externas (<link>) e internas (<style>). Se houver várias, a última declarada prevalece.
  4. Estilos Padrão do Navegador: Estilos que o navegador aplica por padrão (ex: negrito para <strong>).

Herança de Estilos

Algumas propriedades CSS, como color, font-family e font-size, são naturalmente herdadas por elementos filhos de seus pais. A herança tem a menor prioridade de todas; qualquer estilo explicitamente definido para um elemanto filho sempre substituirá um estilo herdado.


<html lang="pt-BR">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Exemplo Herança</title>
</head>
<body>
    <div style="color: darkmagenta;">
        <section style="color: teal;">
            <p>Este parágrafo herdará a cor azul-petróleo.</p>
        </section>
    </div>
</body>
</html>

No exemplo acima, o parágrafo herdará a cor teal (azul-petróleo) da <section>, que é seu ancestral direto. O estilo da <div>, embora também seja um ancestral, tem menor prioridade devido à proximidade da <section>.

Tags: CSS especificidade-css cascata-css seletores-css prioridade-css

Publicado em 7-1 18:47