Especificidade

Suponha que você esteja trabalhando com o seguinte HTML e CSS:

<button class="branding">Hello, Specificity!</button>
button {
  color: red;
}

.branding {
  color: blue;
}

Existem duas regras concorrentes aqui. Uma colorirá o botão de vermelho e a outra de azul. Qual regra é aplicada ao elemento? Compreender o algoritmo da especificação CSS sobre a especificidade é fundamental para entender como o CSS decide entre regras concorrentes.

A especificidade é um dos quatro estágios distintos da cascata, que foi abordada no último módulo, na cascata.

Pontuação de especificidade

Cada regra do seletor obtém uma pontuação. Você pode pensar sobre a especificidade como uma pontuação total e cada tipo de seletor ganha pontos para essa pontuação. O seletor com a maior pontuação vence.

Com a especificidade em um projeto real, o ato de equilíbrio é garantir que as regras CSS que você espera aplicar realmente se apliquem, enquanto geralmente mantém as pontuações baixas para evitar a complexidade. A pontuação deve ser tão alta quanto precisamos, ao invés de almejar a pontuação mais alta possível. No futuro, alguns CSS genuinamente mais importantes podem precisar ser aplicados. Se você tentar a pontuação mais alta, dificultará esse trabalho.

Pontuação de cada tipo de seletor

Cada tipo de seletor ganha pontos. Você adiciona todos esses pontos para calcular a especificidade geral de um seletor.

Seletor universal

Um seletor universal ( * ) não tem especificidade e recebe 0 pontos . Isso significa que qualquer regra com 1 ou mais pontos irá substituí-la

* {
  color: red;
}

Seletor de elemento ou pseudoelemento

Um elemento (tipo) ou pseudo-elemento selector recebe um ponto de especificidade.

Seletor de tipo

div {
  color: red;
}

Seletor de pseudoelemento

::selection {
  color: red;
}

Classe, pseudoclasse ou seletor de atributo

Uma classe, pseudoclasse ou seletor de atributo obtém 10 pontos de especificidade.

Seletor de classe

.my-class {
  color: red;
}

Seletor de pseudoclasse

:hover {
  color: red;
}

Seletor de atributo

[href='#'] {
  color: red;
}

A pseudoclasse :not() em si não adiciona nada ao cálculo de especificidade. No entanto, os seletores passados como argumentos são incluídos no cálculo da especificidade.

div:not(.my-class) {
  color: red;
}

Esta amostra teria 11 pontos de especificidade porque tem um seletor de tipo ( div ) e uma classe dentro de :not().

Seletor de ID

Um seletor de ID obtém 100 pontos de especificidade, contanto que você use um seletor de ID ( #myID ) e não um seletor de atributo ( [id="myID"] ).

#myID {
  color: red;
}

Atributo de estilo inline

CSS aplicado diretamente ao style do elemento HTML, obtém uma pontuação de especificidade de 1.000 pontos. Isso significa que, para substituí-lo no CSS, você deve escrever um seletor extremamente específico.

<div style="color: red"></div>

Regra !important

Por último, um !important no final de um valor CSS obtém uma pontuação de especificidade de 10.000 pontos. Esta é a especificidade mais alta que um item individual pode obter.

Uma !important é aplicada a uma propriedade CSS, de forma que tudo na regra geral (seletor e propriedades) não obtenha a mesma pontuação de especificidade.

.my-class {
  color: red !important; /* 10,000 pontos */
  background: white; /* 10 pontos */
}

Check your understanding

Test your knowledge of specificity scoring

What is the specificity score of a[href="#"]?

1
The a is worth 1 point, but the [href="#"] is worth 10 points.
5
Try again!
11
The a is worth 1 point and the [href="#"] is worth 10 points, making a total score of 11 points.

Especificidade no contexto

A especificidade de cada seletor que corresponde a um elemento é adicionada. Considere este exemplo de HTML:

<a class="my-class another-class" href="#">A link</a>

Este link contém duas classes. Adicione o seguinte CSS e ele obtém 1 ponto de especificidade :

a {
  color: red;
}

Faça referência a uma das classes nesta regra, agora ela tem 11 pontos de especificidade :

a.my-class {
  color: green;
}

Adicione a outra classe ao seletor, agora ela tem 21 pontos de especificidade :

a.my-class.another-class {
  color: rebeccapurple;
}

Adicione o atributo href ao seletor, agora ele tem 31 pontos de especificidade :

a.my-class.another-class[href] {
  color: goldenrod;
}

Finalmente, adicione uma :hover a tudo isso, o seletor termina com 41 pontos de especificidade :

a.my-class.another-class[href]:hover {
  color: lightgrey;
}

Check your understanding

Test your knowledge of specificity scoring

Which of the following selectors is worth 21 points?

article > section
Elements are worth 1 point, there are 2 elements in the selector, making this worth 2 points.
article.card.dark
Elements are worth 1 point, classes are worth 10 points, and with 2 classes and 1 element, that makes this selector worth 21 points.
article:hover a[href]
Elements are worth 1 point, pseudo-classes and attributes are worth 10 points, there are 2 points for the elements, and 20 points for the attributes and classes, makes this selector worth 22 points.

Visualizando a especificidade

Em diagramas e calculadoras de especificidade, a especificidade é frequentemente assim visualizada:

Um diagrama que demonstra dos seletores mais específicos aos menos específicos

O grupo esquerdo são os seletores de id. O segundo grupo é composto por seletores de classe, atributo e pseudoclasse. O grupo final são os seletores de elemento e pseudoelemento.

Para referência, o seguinte seletor é 0-4-1 :

a.my-class.another-class[href]:hover {
  color: lightgrey;
}

Check your understanding

Test your knowledge of specificity visualizing

Which of the following selectors is 1-2-1?

section#specialty.dark
This selector is visualized as 1-1-1.
#specialty:hover li.dark
🎉
[data-state-rad].dark#specialty:hover
This selector is visualized as 1-3-0.
li#specialty section.dark
This selector is visualized as 1-1-2.

Aumentando a especificidade pragmaticamente

Digamos que temos algum CSS parecido com este:

.my-button {
  background: blue;
}

button[onclick] {
  background: grey;
}

Com um HTML semelhante a este:

<button class="my-button" onclick="alert('hello')">Click me</button>

O botão tem fundo cinza, pois o segundo seletor ganha 11 pontos de especificidade (0-1-1). Isso porque ele possui um seletor de tipo (button), que é de 1 ponto e um seletor de atributo ([onclick]), que é de 10 pontos .

A regra anterior .my-button ganha 10 pontos (0-1-0), porque tem um seletor de classe.

Se você quiser dar um impulso a esta regra, repita o seletor de classe desta forma:

.my-button.my-button {
  background: blue;
}

button[onclick] {
  background: grey;
}

Agora, o botão terá um fundo azul, pois o novo seletor obtém uma pontuação de especificidade de 20 pontos (0-2-0).

Uma pontuação de especificidade correspondente faz com que a instância mais recente ganhe

Vamos ficar com o exemplo de botão por enquanto e mudar o CSS para este:

.my-button {
  background: blue;
}

[onclick] {
  background: grey;
}

O botão tem um fundo cinza, porque os dois seletores têm pontuação de especificidade idêntica (0-1-0).

Se você mudar as regras na ordem de origem, o botão ficará azul.

[onclick] {
  background: grey;
}

.my-button {
  background: blue;
}

Esta é a única instância em que o CSS mais recente vence. Para fazer isso, ele deve corresponder à especificidade de outro seletor que visa o mesmo elemento.

Recursos