Compreendendo a Especificidade dos Seletores CSS

A especificidade é um mecanismo fundamental no CSS que determina qual regra de estilo deve ser aplicada a um elemento HTML quando múltiplas declarações tentam estilizá-lo. É um peso atribuído a uma declaração CSS, calculado com base na contagem de cada tipo de seletor utilizado para selecionar o elemento.

Como a Especificidade é Calculada

Cada tipo de seletor contribui com um valor para a especificidade, que pode ser visualizado como uma sequência de quatro números: (A, B, C, D), onde:

  • A: Representa se a declaração possui !important (1 para sim, 0 para não). Declarações !important têm a maior prioridade.
  • B: Representa seletores de ID (por exemplo, #meuId). Cada ID contribui com 100 pontos.
  • C: Representa seletores de classe (por exemplo, .minhaClasse), atributos (por exemplo, [type="text"]) e pseudo-classes (por exemplo, :hover, :nth-child()). Cada um contribui com 10 pontos.
  • D: Representa seletores de elemento (por exemplo, p, div) e pseudo-elementos (por exemplo, ::before, ::first-letter). Cada um contribui com 1 ponto.

Estilos em linha (definidos diretamente no atributo style de um elemento HTML) possuem uma especificidade alta, geralmente considerada como (0, 1, 0, 0) ou (1,0,0,0) se a notação for simplificada, mas são superados por !important.

Regras de Desempate

  1. O seletor com a maior especificidade sempre vence.
  2. Se dois seletores tiverem a mesma especificidade, a declaração que aparece por último no código CSS (ou linkada por último no HTML) será aplicada.
  3. A proximidade do elemento na árvore DOM não afeta a especificidade.

Exemplos de Cálculo de Especificidade

Considere os seguintes seletores e seus cálculos de especificidade:

/* Seletor A: #app > div.wrapper p.text-primary */
/* Especificidade: IDs (1) + Classes (2) + Elementos (2) = (0, 1, 2, 2) */
/* Pontuação: 100 + 10 + 10 + 1 + 1 = 122 */
#app > div.wrapper p.text-primary {
 color: blue;
}

/* Seletor B: div#main-content p:last-of-type */
/* Especificidade: IDs (1) + Classes/Pseudo-classes (1) + Elementos (2) = (0, 1, 1, 2) */
/* Pontuação: 100 + 10 + 1 + 1 = 112 */
div#main-content p:last-of-type {
 color: red;
}

/* Neste caso, o Seletor A (122 pontos) tem maior especificidade que o Seletor B (112 pontos). */
/* A cor do texto será azul. */

Precedência por Ordem no Código

Quando a especificidade é idêntica, a ordem de declaração é crucial:

/* Primeiro arquivo CSS (por exemplo, styles.css) */
.minha-secao {
 background-color: lightblue;
}

/* Segundo arquivo CSS (por exemplo, theme.css), carregado depois de styles.css */
.minha-secao {
 background-color: lightgreen; /* Este prevalecerá se a especificidade for a mesma */
}

<!-- No seu HTML -->
<link rel="stylesheet" href="styles.css">
<link rel="stylesheet" href="theme.css">

<div class="minha-secao">
 Conteúdo da Seção
</div>

A div terá um fundo verde claro, pois theme.css é carregado depois e declara a mesma regra com a mesma especificidade.

A Declaração !important

A palavra-chave !important é uma ferramenta poderosa que pode anular quase todas as outras declarações CSS. Quando anexada a uma propriedade, ela concede a essa propriedade a maior especificidade possível dentro de uma folha de estilo, exceto se houver outra declaração !important com maior especificidade ou uma declaração no estilo de agente do usuário (raro de ocorrer).

.titulo {
 color: purple; /* Especificidade (0,0,1,0) */
}

#cabecalho .titulo {
 color: orange; /* Especificidade (0,1,1,0) */
}

.titulo-principal {
 color: green !important; /* Especificidade (1,0,1,0) - Supera todos os anteriores */
}

<h1 class="titulo titulo-principal" id="cabecalho">
 Meu Título Importante
</h1>

O texto do h1 será verde devido ao !important, mesmo que o seletor #cabecalho .titulo tenha uma especificidade maior em condições normais.

É importante usar !important com moderação, pois ele pode dificultar a depuração e a manutenção do CSS.

Seletores Especiais: :not(), :is() e :where()

Essas pseudo-classes funcionais têm comportamentos distintos em relação à especificidade:

  • :not() e :is():

    A especificidade dessas pseudo-classes é determinada pela especificidade do seletor mais específico dentro de seus argumentos. Elas mesmas não adicionam pontos à especificidade.

    /* Especificidade de (0,1,1) (classe .aviso, elemento p) */
    :not(p).aviso {
     background-color: yellow;
    }
    
    /* Dentro de :is(h1, h2), o seletor mais específico é 'h2', que tem 1 ponto de elemento. */
    /* O seletor completo 'p:is(h1, h2)' tem a especificidade de 'p' (1) + 'h2' (1) = (0,0,0,2) */
    p:is(h1, h2) {
     font-weight: bold;
    }
    
    
  • :where():

    Esta pseudo-classe especial tem uma especificidade de zero. Isso significa que, independentemente dos seletores contidos em seus argumentos, ela não contribuirá com nenhum ponto para a especificidade da regra. Isso a torna ideal para definir estilos base que podem ser facilmente sobrescritos por outras regras.

    /* Especificidade: (0,0,0,0) */
    :where(h1, h2, .minha-classe) {
     margin-top: 0;
     padding-bottom: 0;
    }
    
    

Seeltores que Não Afetam a Especificidade

Alguns seletores e combinadores não adicionam nenhum valor à especificidade:

  • O seletor universal (*).
  • Combinadores (+, >, ~, espaço, ||).

Tags: CSS SeletoresCSS EspecificidadeCSS PrioridadeCSS !important

Publicado em 7-29 01:42