Especificidad CSS

La especificidad en selectores CSS


Curiosamente, la Especificidad CSS es uno de los detalles más importantes de CSS, y a la misma vez es de las cosas que, sorprendemente, mucha gente desconoce, aún cuando debería ser esencial conocerlo.

¿Qué es la Especificidad CSS?

La Especificidad CSS es el nombre que recibe un mecanismo del navegador que se encarga de, en el caso de que exista ambigüedad y hayan varios bloques de estilos compitiendo uno contra otro para dar estilo a un mismo elemento, resolver dicha ambigüedad y decidir cuál es el grupo de estilos «vencedor».

Para ello, el navegador analizar los selectores y le otorga un valor numérico. El selector que tenga el valor numérico más alto, es el que finalmente aplicará sus estilos.

En muchas ocasiones, los desarrolladores piensan que CSS funciona de una forma similar a un lenguaje de programación como Javascript, y que simplemente los estilos vencedores son los que se escriben más abajo en el CSS. No siempre ocurre esto, por eso es importante conocer la Especificidad CSS.

Conflictos de especificidad CSS

Para entenderlo, vamos a ver un ejemplo donde habría un conflicto de especificidad CSS. Observa el siguiente fragmento de código e imaginemos lo que haría el navegador. Recalcar que el mismo elemento HTML tiene tanto id como clase:

#element {
  background: indigo;
  color: white;
}

.container {
  background: red;
}
<div id="element" class="container">Hola, mi página es Manz.dev</div>

En este caso, tenemos un conflicto, ya que existe ambigüedad. Ambos bloques están seleccionando el mismo elemento y están compitiendo para la propiedad CSS background. Como se puede ver en la demo, el vencedor es el selector #element. Sin embargo, muchas personas piensan que, como se seleccionan ambos, vence el que está más abajo porque sobreescribe el anterior. Esto es erróneo.

¿Cómo se calcula la Especificidad?

El navegador tiene un sistema llamado Especificidad CSS, donde en situaciones de conflicto como la anterior, calculará que selector es más específico, siguiendo unas ciertas normas, y obtienendo como resultado un valor numérico.

Dicho valor numérico se suele representar con 3 cifras, separadas por comas: A,B,C:

Valor Descripción
Valor A Número de veces que aparece un #id en el selector.
Valor B Número de veces que aparece una .clase, [atributo] o :pseudoclase en el selector.
Valor C Número de veces que aparece un elemento o un ::pseudoelemento en el selector.

Teniendo en cuenta esto, veamos algunos ejemplos con diferentes selectores CSS y calculemos su cifra de especificidad CSS. Recuerda que cuanto más alta sea, más específico es el selector y mayor prioridad de que gane sobre otros selectores en conflicto:

div { ... }                   /* 0,0,1 (1 elemento HTML) */
div div { ... }               /* 0,0,2 (2 elementos HTML) */
#pagina div { ... }           /* 1,0,1 (1 id y 1 elemento HTML) */
#pagina div:hover { ... }     /* 1,1,1 (1 id, 1 pseudoclase y 1 elemento HTML) */
#pagina div:hover a { ... }   /* 1,1,2 (1 id, 1 pseudoclase y 2 elementos HTML) */
#pagina .sel:hover>a { ... }  /* 1,2,1 (1 id, 1 clase, 1 pseudoclase y 1 elemento HTML) */

Estos cálculos no hace falta hacerlos a mano o mentalmente, existen calculadoras de especificidad que pueden darte el valor por si tienes curiosidad por saber cuál tiene mayor o menor especificidad. De hecho, las DevTools del navegador, también suelen mostrar la especificidad si mueves el ratón sobre el selector.

Tienes dos excelentes calculadoras de especificidad en Calculadora de Keegan y en Calculadora de Polypane donde podrás calcular la especificidad de un selector CSS rápida y cómodamente.

Excepciones de Especificidad CSS

Recuerda también que hay ciertas excepciones a la hora de calcular la especificidad (puedes comprobarlo en las calculadoras):

Excepción Cómo se modifica su especificidad
1️⃣ Combinadores :is(), :not() o :has() La especificidad del selector más específico en el interior de los paréntesis.
2️⃣ Pseudoclases :nth-child() o :nth-last-child() Se suma la especificidad de la pseudoclase más el selector más específico.
3️⃣ La pseudoclase :where() Se reemplaza su especificidad por 0.

Recuerda que hay varios mecanismos para controlar la cascada de CSS. Puedes echar un vistazo a todos ellos en el post sobre la cascada de CSS.

¿Quién soy yo?

Soy Manz, vivo en Tenerife (España) y soy streamer partner en Twitch y profesor. Me apasiona el universo de la programación web, el diseño y desarrollo web y la tecnología en general. Aunque soy full-stack, mi pasión es el front-end, la terminal y crear cosas divertidas y locas.

Puedes encontrar más sobre mi en Manz.dev