Calculadora de especificidad de selectores CSS
La especificidad CSS decide qué declaración puede imponerse cuando varias compiten, antes de considerar el orden de aparición y otras reglas de la cascada.
Ejecutar — gratis
Esta calculadora acepta un selector, valida su estructura y devuelve el recuento habitual de cuatro partes: estilos en línea, ID, clases o atributos o pseudoclases, y tipos de elemento o pseudoelementos. También aplica las reglas especiales de selectores modernos como :is(), :not(), :has(), :where() y :nth-child(). Puede usarla para explicar una sobrescritura inesperada, comparar selectores durante una refactorización o incorporar una comprobación fiable a sus herramientas de desarrollo.
Cómo interpretar el resultado de cuatro partes
El resultado se expresa como (en línea, ID, clase, tipo). La primera posición representa declaraciones de estilo en línea; como esta herramienta recibe un selector y no un atributo style de HTML, su valor siempre es cero. La segunda cuenta selectores de ID como <code>#checkout</code>. La tercera agrupa selectores de clase, de atributo y pseudoclases; por tanto, <code>.button</code>, <code>[disabled]</code> y <code>:hover</code> suman una unidad cada uno. La cuarta cuenta selectores de tipo de elemento y pseudoelementos, de modo que <code>button</code> y <code>::before</code> añaden una unidad. Los selectores universales y combinadores no suman nada. Compare la tupla de izquierda a derecha, sin convertirla en una suma decimal: un ID supera cualquier cantidad de clases y una clase supera cualquier cantidad de tipos. Los campos con nombre facilitan el uso programático, mientras que el array de especificidad conserva la forma visual convencional. Recuerde que la especificidad es solo una parte de la cascada. El origen, la importancia, las capas, la proximidad de ámbito y el orden de aparición aún pueden decidir qué declaración vence en una página real.
Reglas de las pseudoclases funcionales
Las pseudoclases funcionales modernas exigen algo más que contar cada token. <code>:is()</code>, <code>:not()</code> y <code>:has()</code> aportan la especificidad del selector más específico de su lista de argumentos; la envoltura no añade una clase. En cambio, <code>:where()</code> siempre aporta cero, aunque su argumento contenga un ID. Por eso resulta útil para valores predeterminados de bibliotecas que deben ser fáciles de sobrescribir. Las pseudoclases estructurales <code>:nth-child()</code> y <code>:nth-last-child()</code> añaden una pseudoclase y, si incluyen una lista opcional tras <code>of</code>, también aportan el miembro más específico. Las demás pseudoclases funcionales suman en el nivel de clase, mientras que los pseudoelementos suman en el nivel de tipo. El analizador reconoce además selectores relativos dentro de <code>:has()</code>, caracteres escapados en identificadores, valores de atributo con puntuación, espacios de nombres y las formas heredadas con un solo signo de dos puntos: <code>:before</code>, <code>:after</code>, <code>:first-line</code> y <code>:first-letter</code>. Estas diferencias reflejan el razonamiento real sobre CSS actual, en lugar de tratar los paréntesis como texto opaco.
Validación para detectar errores de selector
Un número de especificidad solo sirve si la entrada es un selector plausible. Por ello, la calculadora rechaza campos ausentes, texto vacío, cadenas sin terminar, corchetes o paréntesis sin cerrar, combinadores mal formados, identificadores ausentes tras un punto o una almohadilla y otros errores estructurales. Acepta un selector cada vez. Una coma en el nivel superior crea una lista cuyos miembros pueden tener especificidades distintas, así que esa entrada se rechaza y se solicita un único selector; calcule cada miembro por separado al comparar una lista de reglas. La longitud está limitada para que la ejecución sea predecible, y el algoritmo no utiliza una sesión de navegador, conexión de red, valores aleatorios ni reloj. Así, una misma entrada genera el mismo JSON en el widget local, una llamada API, una prueba o una comprobación de compilación. Use el resultado como diagnóstico concreto: compare los selectores y, si la especificidad no basta para explicar el estilo, revise las capas de cascada, <code>!important</code>, la herencia y el orden de aparición.
Qué puede hacer con ella
Depurar una sobrescritura persistente
Compare selectores en conflicto y descubra qué componente hace que una regla supere a otra.
Revisar refactorizaciones de estilos
Compruebe que un selector simplificado reduce la especificidad sin introducir por accidente un ID ni peso adicional de pseudoclase.
Mejorar herramientas de desarrollo
Añada validación determinista y recuentos estructurados a un linter, editor o informe de integración continua.
Preguntas frecuentes
¿Qué significa el valor de estilos en línea?
Representa declaraciones de estilo en línea. Aquí siempre vale cero porque la entrada es un selector CSS, no un atributo style de HTML.
¿Aumenta :where() la especificidad?
No. :where() y todo su argumento siempre aportan cero, aunque se sigue validando la estructura del selector que contienen.
¿Cómo se cuentan :is(), :not() y :has()?
Aportan la especificidad del selector más específico de su lista de argumentos; la pseudoclase funcional no añade peso por sí misma.
¿Puedo enviar una lista de selectores separada por comas?
No. Envíe cada selector de nivel superior por separado, pues los miembros de una lista pueden tener especificidades distintas.
¿Gana siempre la especificidad más alta?
No. El origen, la importancia, las capas, la proximidad de ámbito y el orden de aparición pueden tener prioridad o resolver empates.
¿Cuánto cuesta una solicitud API?
Cada solicitud API cuesta $0.002. La versión del navegador puede ejecutarse localmente sin enviar el selector a un servidor.
Para desarrolladores — acceso por API
Todo lo de esta página está disponible por programación. Esta sección es para equipos que quieren integrarlo en sus sistemas; el resto puede usar la herramienta de arriba sin más.
Endpoint de API
¿Prefiere automatizarlo? Un POST autenticado crea la tarea; el resultado llega por webhook o enlace firmado. La misma capacidad también se ejecuta aquí en la web, por email y desde Telegram — y pronto también desde nuestra app.
Llámela desde su stack
curl -X POST https://api.kit.forhosting.com/web/css-specificity-calc \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"selector":"article#main.card[data-state='\''open'\'']:hover > h2::before"}'const res = await fetch("https://api.kit.forhosting.com/web/css-specificity-calc", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"selector": "article#main.card[data-state='open']:hover > h2::before"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/web/css-specificity-calc",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"selector": "article#main.card[data-state='open']:hover > h2::before"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/web/css-specificity-calc", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"selector":"article#main.card[data-state=\'open\']:hover > h2::before"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"selector":"article#main.card[data-state='open']:hover > h2::before"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/web/css-specificity-calc", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Ejemplo de solicitud
{
"selector": "article#main.card[data-state='open']:hover > h2::before"
}Ejemplo de respuesta
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "web.css_specificity_calc",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}La API es asíncrona: la llamada devuelve un task_id al instante y el resultado llega por webhook. El polling está limitado a 1 req/s por tarea.
Precio
Precio publicado — sin tokens ni créditos inventados. Una tarea fallida no se cobra.
Límites
max_chars | 10000 |
Errores
| HTTP | Código | Significado |
|---|---|---|
401 | unauthorized | API key ausente o inválida. |
402 | insufficient_balance | El saldo no cubre el precio de la tarea. |
404 | unknown_type | El tipo de tarea no existe. |
429 | rate_limited | Demasiadas peticiones. Use el webhook en vez de sondear. |