Especificidad

Podcast de CSS - 003: Especificidad

Supongamos que trabajas con los siguientes HTML y CSS:

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

.branding {
  color: blue;
}

Hay dos reglas que compiten aquí. Una de ellas lo coloreará de rojo y la otra, de azul. ¿Qué regla se aplica al elemento? Comprender el algoritmo de la especificación de CSS sobre la especificidad es la clave para entender cómo decide CSS entre las reglas competidoras.

La especificidad es una de las cuatro etapas diferentes de la cascada que vimos en el módulo anterior, sobre la cascada.

Puntuación de especificidad

Cada regla del selector obtiene una puntuación. Puedes pensar en la especificidad como una puntuación total y cada tipo de selector gana puntos para esa puntuación. El selector con la puntuación más alta gana.

Con la especificidad en un proyecto real, El equilibrio es asegurarse de que las reglas de CSS que espera aplicar realmente sí se apliquen. al tiempo que, por lo general, mantienen las puntuaciones bajas para evitar la complejidad. La puntuación solo debe ser tan alta como sea necesario, en lugar de intentar obtener la puntuación más alta posible. En el futuro, es posible que se deban aplicar algunos CSS realmente más importantes. Si buscas la puntuación más alta, te pondrás más difícil.

Puntuación de cada tipo de selector

Cada tipo de selector gana puntos. Suma todos estos puntos para calcular la especificidad general de un selector.

Selector universal

Un selector universal (*) No tiene especificidad y obtiene 0 puntos. Esto significa que cualquier regla con 1 o más puntos la anulará a ella.

* {
  color: red;
}

Selector de elemento o seudoelemento

Un elemento (tipo) o seudoelemento el selector obtiene 1 punto de especificidad .

Selector de tipo

div {
  color: red;
}

Selector de seudoelemento

::selection {
  color: red;
}

Selector de clase, seudoclase o atributo

Una clase seudoclase o El selector atributo obtiene 10 puntos de especificidad.

Selector de clases

.my-class {
  color: red;
}

Selector de pseudoclases

:hover {
  color: red;
}

Selector de atributos

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

La :not() no agrega nada al cálculo de especificidad. Sin embargo, los selectores pasados como argumentos sí se agregan al cálculo de especificidad.

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

Esta muestra tendría 11 puntos de especificidad porque tiene un selector de tipo (div) y una clase dentro del :not().

Selector de ID

Un ID el selector obtiene 100 puntos de especificidad, siempre que utilices un selector de ID (#myID) y no un selector de atributos ([id="myID"]).

#myID {
  color: red;
}

Atributo de estilo intercalado

CSS aplicado directamente al atributo style del elemento HTML Obtiene una puntuación de especificidad de 1,000 puntos. Esto significa que, para anularlo en CSS, debes escribir un selector muy específico.

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

Regla !important

Por último, un !important al final de un valor del CSS obtiene una puntuación de especificidad de 10,000 puntos. Esta es la especificidad más alta que puede obtener un elemento individual.

Se aplica una regla !important a una propiedad de CSS. por lo que todo en la regla general (selector y propiedades) no recibe la misma puntuación de especificidad.

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

Verifica tus conocimientos

Pon a prueba tus conocimientos sobre las puntuaciones de especificidad

¿Cuál es la puntuación de especificidad de a[href="#"]?

1
a vale 1 punto, pero [href="#"] vale 10 puntos.
5
Vuelve a intentarlo.
11
La a vale 1 punto y la [href="#"] vale 10 puntos, lo que da una puntuación total de 11 puntos.

Especificidad en contexto

La especificidad de cada selector que coincide con un elemento se suma en conjunto. Considera este HTML de ejemplo:

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

Este vínculo tiene dos clases. Agrega el siguiente CSS y obtendrás 1 punto de especificidad:

a {
  color: red;
}

Haz referencia a una de las clases de esta regla ahora tiene 11 puntos de especificidad:

a.my-class {
  color: green;
}

Agrega la otra clase al selector ahora tiene 21 puntos de especificidad:

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

Agrega el atributo href al selector. ahora tiene 31 puntos de especificidad:

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

Por último, agrega una seudoclase :hover a todo eso. el selector termina con 41 puntos de especificidad:

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

Verifica tus conocimientos

Pon a prueba tus conocimientos sobre las puntuaciones de especificidad

¿Cuál de los siguientes selectores vale 21 puntos?

article > section
Los elementos valen 1 punto, ya que hay 2 elementos en el selector, por lo que vale 2 puntos.
article.card.dark
Los elementos valen 1 punto, las clases valen 10 puntos y, con 2 clases y 1 elemento, este selector vale 21 puntos.
article:hover a[href]
Los elementos valen 1 punto, las seudoclases y los atributos valen 10 puntos, hay 2 puntos para los elementos y 20 puntos para los atributos y las clases, por lo que este selector vale 22 puntos.

Visualiza la especificidad

En diagramas y calculadoras de especificidad, la especificidad a menudo se visualiza de la siguiente manera:

Diagrama que muestra los selectores más específicos a menos específicos

El grupo de la izquierda es id selectores. El segundo grupo son los selectores de clase, atributo y seudoclase. El último grupo son los selectores de elementos y seudoelementos.

Como referencia, el siguiente selector es 0-4-1:

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

Verifica tus conocimientos

Pon a prueba tus conocimientos sobre la visualización de la especificidad

¿Cuál de los siguientes selectores es 1-2-1?

section#specialty.dark
Este selector se visualiza como 1-1-1.
#specialty:hover li.dark
🎉
[data-state-rad].dark#specialty:hover
Este selector se visualiza como 1-3-0.
li#specialty section.dark
Este selector se visualiza como 1-1-2.

Especificidad creciente pragmática

Supongamos que tenemos algunas CSS que se ven de la siguiente manera:

.my-button {
  background: blue;
}

button[onclick] {
  background: grey;
}

Con HTML como este:

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

El botón tiene un fondo gris, porque el segundo selector obtiene 11 puntos de especificidad (0-1-1). Esto se debe a que tiene un selector de tipo (button), que es 1 punto y un selector de atributos ([onclick]), que es de 10 puntos.

La regla anterior, .my-button, obtiene 10 puntos (0-1-0), porque tiene un selector de clase.

Si quieres darle un impulso a esta regla, repite el selector de clase de la siguiente manera:

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

button[onclick] {
  background: grey;
}

Ahora, el botón tendrá un fondo azul, porque el nuevo selector obtiene una puntuación de especificidad de 20 puntos (0-2-0).

Una puntuación de especificidad coincidente gana la instancia más reciente

Por ahora, quedémonos con el ejemplo del botón y cambiemos el CSS a esto:

.my-button {
  background: blue;
}

[onclick] {
  background: grey;
}

El botón tiene un fondo gris, porque ambos selectores tienen una puntuación de especificidad idéntica (0-1-0).

Si cambias las reglas en el orden de origen, entonces el botón sería azul.

[onclick] {
  background: grey;
}

.my-button {
  background: blue;
}

Este es el único caso en el que ganan los CSS más nuevos. Para hacerlo, debe coincidir con la especificidad de otro selector que se oriente al mismo elemento.

Recursos