Calculadora de especificidad CSS
ReferenciaCalcula la especificidad (A, B, C) de cualquier selector CSS — IDs, clases, atributos, pseudoclases y elementos — compara varios selectores a la vez y muestra cómo aporta cada parte. Soporta :is(), :not() y :where().
En esta página
¿Qué es la especificidad CSS?#
Cuando dos reglas CSS intentan fijar la misma propiedad en el mismo elemento, el navegador no elige la escrita en último lugar: elige la de especificidad más alta. La especificidad es una puntuación de tres partes (A, B, C) que la cascada compara como un número de versión:
- A — selectores de ID (
#header). - B — selectores de clase (
.btn), selectores de atributo ([type=email]) y pseudoclases (:hover,:focus). - C — selectores de tipo (
div,a) y pseudoelementos (::before,::first-line).
A se compara primero; un empate cae a B, luego a C. Un ID (1,0,0) vence a cualquier número de clases (0,99,99), que a su vez vencen a cualquier número de tipos. El universal *, los combinadores (> + ~) y el selector de anidamiento & no añaden nada.
Esta página calcula esa tupla para cualquier selector que pegues (incluidas las pseudoclases funcionales modernas :is(), :where(), :not(), :has() y la cláusula of S de :nth-child()), ordena una lista de selectores y muestra exactamente qué piezas contribuyeron con qué. Es la forma más rápida de responder a la pregunta universal de CSS: «¿por qué pierde mi regla?».
Cómo se usa#
- Haz clic en Ejemplo para cargar un conjunto de selectores resuelto, o limpia la caja y pega los tuyos. Puedes introducir un selector suelto (
#nav .item) o una regla completa (#nav .item { color: red }); la herramienta lee la parte anterior a{. - ¿Varios selectores? Sepáralos con comas: se ordenan de más a menos específicos y el ganador se marca.
- El panel derecho lista cada selector con su tupla
(A, B, C)y un desglose coloreado de cada pieza que contribuye (rojo = ID, azul = clase/atributo/pseudoclase, verde = tipo/pseudoelemento), para que veas por qué la puntuación es la que es. - La leyenda coloreada arriba a la derecha te recuerda qué punto mapea a A / B / C.
- Si tu regla contenía
!important, aparece una nota informativa:!importantes una sobreescritura a nivel de declaración que se sienta por encima de la comparación de especificidad, no dentro de ella.
Características clave#
- Correcto en los casos difíciles.
:where()siempre contribuye(0,0,0);:is()/:not()/:has()toman la mayor especificidad entre sus argumentos; el:beforeheredado y la cláusulaof Sde:nth-child()se manejan según Selectors Level 4. - Ordena una lista separada por comas y marca los empates, para que veas de un vistazo cuál de varias reglas ganará.
- Desglose por pieza. Cada
#id,.class,[attr], pseudoclase, pseudoelemento y tipo se detalla con el texto exacto que contribuyó. - Tolerante con reglas completas. Pega
a:hover { text-decoration: underline }: los comentarios se eliminan y el bloque de declaraciones se ignora automáticamente. - 100 % local. Nada sale de la página; no se recupera ni se evalúa ninguna hoja de estilos.
Ejemplo práctico#
Un puzzle de depuración común: tres reglas apuntan al mismo enlace y el color equivocado gana. Pégalas en la caja:
.button:hover
:is(.card, #hero) .button
a.button
La salida las ordena:
| Rango | Selector | Especificidad (A, B, C) |
|---|---|---|
| 1 | :is(.card, #hero) .button | (1, 1, 0) — ganador |
| 2 | .button:hover | (0, 2, 0) |
| 3 | a.button | (0, 1, 1) |
El ganador no es el que tiene más clases. :is(.card, #hero) hereda la mayor especificidad de sus argumentos: #hero es un ID, así que :is() aporta (1,0,0) aunque .card solo sería (0,1,0). Añadir .button sube B en uno, lo que da (1,1,0). Ese único ID en la columna A vence a las dos clases de .button:hover (0,2,0): esa es la sorpresa exacta que hace a :is() peligroso en CSS de producción.
Si necesitaras la misma agrupación sin subir la especificidad, cambiarías :is() por :where():
:where(.card, #hero) .button → (0, 1, 0)
Ahora empata con a.button menos el tipo, y el orden de fuente decide. Esa es toda la razón por la que existe :where().
Preguntas frecuentes#
¿Por qué un ID vence a cientos de clases?#
La especificidad compara columnas de izquierda a derecha como un número de versión, no como un total sumado. (1,0,0) va «por delante» de (0,999,999) porque la columna A es distinta de cero en el primero y cero en el segundo; las columnas B y C ni se consultan. Es deliberado: los IDs estaban pensados para ser únicos inequívocos.
¿Cuál es la diferencia entre :is() y :where()?#
Son idénticos en lo que casan, pero opuestos en especificidad. :is(.a, #b) toma la mayor especificidad entre sus argumentos (así que #b la pone en (1,0,0)); :where(.a, #b) siempre contribuye (0,0,0) independientemente de sus argumentos. Usa :where() para valores por defecto de baja especificidad que puedas sobrescribir fácilmente, y :is() cuando de verdad quieras que el selector combinado compita.
¿Un atributo en línea style="…" vence a estos?#
Sí. Los estilos en línea superan a cualquier regla basada en selectores en la cascada normal (se sientan en un origen superior), así que ninguna tupla de selector sobrescribirá un estilo en línea sin !important. Es un eje aparte de la puntuación (A,B,C), por eso la herramienta evalúa solo selectores.
¿Dónde encaja !important?#
!important es un indicador a nivel de declaración, no una propiedad del selector: no cambia la tupla (A,B,C). Mueve la declaración entera a un origen de cascada superior, así que una regla !important vence a una regla normal independientemente de la especificidad. La herramienta anota su presencia de forma informativa, pero la mantiene fuera de la puntuación.