Podcast do CSS - 003: Especificidade
Suponha que você esteja trabalhando com o seguinte HTML e CSS:
<button class="branding">Hello, Specificity!</button>
button {
color: red;
}
.branding {
color: blue;
}
Há duas regras conflitantes aqui. Um vai colorir o botão de vermelho e o outro de azul. Qual regra é aplicada ao elemento? Entender o algoritmo da especificação do CSS sobre especificidade é a chave para entender como o CSS decide entre regras concorrentes.
A especificidade é um dos quatro estágios distintos da cascata, abordados no último módulo, sobre a cascata.
Pontuação de especificidade
Cada regra de seletor recebe uma pontuação. Você pode pensar na especificidade como uma pontuação total, e cada tipo de seletor ganha pontos em relação a essa pontuação. Vence o seletor com a maior pontuação.
Com a especificidade de um projeto real, o equilíbrio é garantir que as regras CSS que você espera aplicar sejam realmente aplicadas, mantendo as pontuações baixas para evitar complexidade. A pontuação precisa ser a mais alta possível, em vez de ter a maior pontuação possível. No futuro, pode ser necessário usar alguns CSS genuinamente mais importantes. Se você conseguir a pontuação mais alta, fará o trabalho difícil.
Pontuação de cada tipo de seletor
Cada tipo de seletor gera 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 um ou mais pontos a substituirá
* {
color: red;
}
Seletor de elemento ou pseudoelemento
Um seletor de elemento (tipo) ou pseudoelemento recebe 1 ponto de especificidade .
Seletor de tipo
div {
color: red;
}
Seletor de pseudoelementos
::selection {
color: red;
}
Seletor de classe, pseudoclasse ou atributo
Um seletor de classe, pseudoclasse ou atributo recebe 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()
não adiciona nada ao cálculo de especificidade.
No entanto, os seletores transmitidos como argumentos são adicionados ao cálculo de especificidade.
div:not(.my-class) {
color: red;
}
Essa amostra teria 11 pontos de especificidade,
porque tem um seletor de tipo (div
) e uma classe dentro da :not()
.
Seletor de ID
Um seletor de ID
recebe 100 pontos de especificidade,
desde que você use um seletor de ID (#myID
) e não um seletor de atributo ([id="myID"]
).
#myID {
color: red;
}
Atributo de estilo inline
Quando aplicado diretamente ao atributo style
do elemento HTML, o CSS
recebe uma pontuação de especificidade de 1.000 pontos.
Isso significa que, para fazer a substituição no CSS,
é necessário criar um seletor extremamente específico.
<div style="color: red"></div>
Regra !important
Por fim, um !important
ao final de um valor de CSS recebe uma pontuação de especificidade de 10.000 pontos.
Essa é a especificidade mais alta que um item individual pode conseguir.
Uma regra !important
é aplicada a uma propriedade CSS. Portanto, nada na regra geral (seletor e propriedades) não recebe a mesma pontuação de especificidade.
.my-class {
color: red !important; /* 10,000 points */
background: white; /* 10 points */
}
Teste seu conhecimento
Teste seus conhecimentos sobre a pontuação de especificidade
Qual é a pontuação de especificidade de a[href="#"]
?
a
vale 1 ponto, mas o [href="#"]
vale 10 pontos.a
vale 1 ponto, e [href="#"]
vale 10 pontos, totalizando 11 pontos.Especificidade no contexto
A especificidade de cada seletor que corresponde a um elemento é somada. Considere este exemplo de HTML:
<a class="my-class another-class" href="#">A link</a>
Este link tem duas classes. Adicione o CSS abaixo e ele vai ter um ponto de especificidade:
a {
color: red;
}
Faça referência a uma das classes dessa regra, que agora tem 11 pontos de especificidade:
a.my-class {
color: green;
}
Adicione a outra classe ao seletor, que agora tem 21 pontos de especificidade:
a.my-class.another-class {
color: rebeccapurple;
}
Adicione o atributo href
ao seletor,
que agora tem 31 pontos de especificidade:
a.my-class.another-class[href] {
color: goldenrod;
}
Por fim, adicione uma pseudoclasse :hover
a tudo isso.
O seletor termina com 41 pontos de especificidade:
a.my-class.another-class[href]:hover {
color: lightgrey;
}
Teste seu conhecimento
Teste seus conhecimentos sobre a pontuação de especificidade
Qual dos seguintes seletores vale 21 pontos?
article > section
article.card.dark
article:hover a[href]
Como visualizar a especificidade
Em diagramas e calculadoras de especificidade, a especificidade geralmente é visualizada assim:
O grupo à esquerda são seletores de id
.
O segundo grupo são seletores de classe, atributo e pseudoclasse.
O grupo final são seletores de elementos e pseudoelementos.
Para referência, o seletor a seguir é 0-4-1
:
a.my-class.another-class[href]:hover {
color: lightgrey;
}
Teste seu conhecimento
Teste seus conhecimentos sobre visualização de especificidade
Qual dos seguintes seletores é 1-2-1
?
section#specialty.dark
1-1-1
.#specialty:hover li.dark
[data-state-rad].dark#specialty:hover
1-3-0
.li#specialty section.dark
1-1-2
.Aumentando pragmaticamente a especificidade
Vamos supor que temos um CSS com a seguinte aparência:
.my-button {
background: blue;
}
button[onclick] {
background: grey;
}
Com HTML semelhante a este:
<button class="my-button" onclick="alert('hello')">Click me</button>
O botão tem um plano de fundo cinza
porque o segundo seletor ganha 11 pontos de especificidade (0-1-1
).
Isso ocorre porque ele tem um seletor de tipo (button
),
que é 1 ponto, e um seletor de atributo ([onclick]
), que tem 10 pontos.
A regra anterior (.my-button
) recebe 10 pontos (0-1-0
),
porque tem um seletor de classe.
Se você quiser dar um impulso a essa regra, repita o seletor de classe desta forma:
.my-button.my-button {
background: blue;
}
button[onclick] {
background: grey;
}
Agora, o botão terá um plano de fundo azul,
porque o novo seletor recebe uma pontuação de especificidade de 20 pontos (0-2-0
).
Uma pontuação de especificidade correspondente gera a vitória da instância mais recente
Vamos continuar com o exemplo do botão por enquanto e mudar o CSS para este:
.my-button {
background: blue;
}
[onclick] {
background: grey;
}
O botão tem um plano de fundo cinza,
porque os dois seletores têm uma pontuação de especificidade idêntica (0-1-0
).
Se você alterar as regras na ordem de origem, o botão ficará azul.
[onclick] {
background: grey;
}
.my-button {
background: blue;
}
Essa é a única situação em que o CSS mais recente prevalece. Para isso, ele precisa corresponder à especificidade de outro seletor que segmente o mesmo elemento.