FreeToGenerate.com

Los id valen 100 y las clases 10, así que once clases ganan a un id, ¿no? Pues no, y once es justo donde ese atajo empieza a mentir.

0-11-0

Cómo se ha contado cada parte

  • .btnBUn selector de clase, que cuenta en la segunda columna.
  • .btn-primaryBUn selector de clase, que cuenta en la segunda columna.
  • .is-activeBUn selector de clase, que cuenta en la segunda columna.
  • .is-largeBUn selector de clase, que cuenta en la segunda columna.
  • .has-iconBUn selector de clase, que cuenta en la segunda columna.
  • .is-roundedBUn selector de clase, que cuenta en la segunda columna.
  • .is-blockBUn selector de clase, que cuenta en la segunda columna.
  • .is-loadingBUn selector de clase, que cuenta en la segunda columna.
  • .is-disabledBUn selector de clase, que cuenta en la segunda columna.
  • .is-focusBUn selector de clase, que cuenta en la segunda columna.
  • .is-hoverBUn selector de clase, que cuenta en la segunda columna.
A
A — identificadores
B
B — clases, atributos y pseudoclases
C
C — etiquetas y pseudoelementos

Cuál gana

0-11-0vs1-0-0

Gana el segundo selector

La puntuación en base 10 que se enseña siempre

Puntuación: 110 vs 100

El atajo se equivoca aquí. La especificidad son tres números que se comparan columna a columna, no un total: por eso ninguna cantidad de clases gana nunca a un id, por alta que sea la puntuación.

También disponible en: English · Português · Français · العربية

Calculadora de especificidad CSS

La especificidad de cualquier selector como los tres números que compara la cascada de verdad, con cada parte justificada y la respuesta del atajo al lado de la real.

¿Qué es la especificidad en CSS?

Cuando dos reglas CSS se aplican al mismo elemento y tocan la misma propiedad, la especificidad decide cuál gana. Se calcula solo a partir del selector (no de dónde esté la regla ni de lo complicada que parezca) y la especificación de selectores la define como tres recuentos, no como un número.

El primero, A, es el número de selectores de id. El segundo, B, cuenta juntos los selectores de clase, los de atributo y las pseudoclases: un selector de atributo pesa exactamente lo mismo que una clase. El tercero, C, cuenta los selectores de etiqueta y los pseudoelementos. El selector universal no cuenta nada.

Pega un selector arriba y obtienes esos tres números, más una línea por cada parte que explica en qué columna cayó y por qué. Si pones un segundo selector, te dice cuál de los dos ganaría.

Cómo usarla

  1. Escribe o pega un selector. Desde div hasta #nav .item:not(.disabled)::before. Las listas de selectores separadas por comas también valen, y cada entrada se cuenta por su cuenta.
  2. Lee el desglose, no solo el total. Cada selector simple tiene su propia línea diciendo en qué columna contó y por qué, así que un total sorprendente queda explicado y no simplemente afirmado.
  3. Añade un segundo selector para comparar. Obtienes el ganador y, al lado, la puntuación en base 10, con un aviso en los casos en los que ese atajo apunta al lado contrario.

Por qué once clases no ganan a un id

Casi todo el mundo aprende la especificidad como aritmética: un id vale 100, una clase 10, una etiqueta 1, se suma y gana el número más grande. Es una mentira útil que funciona para casi cualquier selector que alguien escriba, y que deja de funcionar sin avisar.

La especificación es explícita: los tres números se comparan de columna en columna. Gana quien tenga la A mayor, y solo si las A empatan se mira la B, y solo entonces la C. No hay acarreo, ni total, ni tipo de cambio. Un id gana a cualquier cantidad de clases: a cien, a mil.

Once es donde el atajo empieza a mentir, y eso no es una suposición. Once clases puntúan 110 frente a los 100 de un id, así que la aritmética dice que ganan las clases mientras la cascada dice que gana el id. Diez clases siguen puntuando 100, un empate que el atajo resuelve igual que la regla real por pura casualidad. La herramienta viene con exactamente ese par cargado para que veas a los dos modelos discrepar en vez de creértelo.

Y tampoco es un caso hipotético. Una hoja de estilos de utilidades apila clases sobre un mismo elemento como cosa normal, y la especificación señala que repetir un selector simple sí aumenta la especificidad: .btn.btn.btn es 0-3-0. Once queda más cerca de lo que parece.

Las partes que pillan a la gente

Cuatro pseudoclases tienen reglas propias, y ahí es donde fallan los cálculos a mano. :is(), :not() y :has() no se cuentan a sí mismas: cada una toma la especificidad del selector más específico que lleve dentro, así que :not(#a) vale un id entero. :where() es lo contrario y es la útil: se sustituye por cero, de modo que lo de dentro no aporta nada por específico que parezca, y eso es justo lo que la convierte en la herramienta adecuada para estilos por defecto que quieres que sean fáciles de sobrescribir.

:nth-child() y :nth-last-child() son el par oscuro. Cuentan como una pseudoclase por sí mismas y luego suman el selector más específico de una cláusula of si la hay, así que :nth-child(2n of .item) es 0-2-0 y no 0-1-0.

Después está una trampa puramente histórica. :before, :after, :first-line y :first-letter son pseudoelementos escritos con dos puntos simples, algo permitido por compatibilidad con CSS2. El punto simple hace que parezcan pseudoclases, y aun así se cuentan en la tercera columna junto a las etiquetas. Cualquier otro nombre con dos puntos simples es una pseudoclase de verdad y cuenta en la segunda.

Límites honestos

La especificidad es solo un paso de la cascada, y esta página calcula ese paso y nada más. Antes van el origen y la importancia: una declaración con !important gana a una normal digan lo que digan los selectores, y las capas de cascada también se miran antes que la especificidad. Los estilos en línea quedan fuera de la terna del selector, y no hay selector que puedas escribir que los supere. Después de la especificidad, si dos reglas siguen empatadas, gana la que vaya más tarde en el código, que es lo que significa aquí el resultado de empate.

El cálculo también da por hecho que el selector es válido. Esto lee lo que escribes sin comprobar que un navegador lo aceptaría, así que una errata se cuenta en vez de rechazarse, y las pseudoclases con prefijo de fabricante o recién propuestas se tratan como corrientes salvo que estén entre los casos especiales de arriba.

Otra cosa que conviene saber: la especificación permite que las implementaciones recorten los tres valores si se quedan sin espacio, así que un selector absurdo puede acabar topado en un navegador real en lugar de contado con exactitud. Nada de lo que escribas a mano se acerca.

Los números de aquí se comprobaron contra los catorce ejemplos resueltos de la propia especificación y, aparte, contra una implementación de referencia sobre 980 selectores generados, sin ninguna discrepancia.

¿Por qué es gratis?

Porque no cuesta nada mantenerla. El análisis y el recuento ocurren en tu navegador; no se sube ningún selector, ningún servidor ve tu hoja de estilos y no hay cuenta.

Las reglas salen de la especificación de selectores de CSS y no de un tutorial, y las pruebas que las comprueban están guardadas junto al código, incluidos los ejemplos de la propia especificación, que es un listón más alto que coincidir con otra calculadora.