DevPath · Aprende a programar ESPTEN

CSS: selectores, cascada y especificidad

Especificidad y !important

¿Qué es la especificidad?

Aquí está la otra mitad del misterio "¿por qué mi CSS no se aplica?". Cuando dos reglas de igual origen chocan, no gana la última sin más: gana la de mayor especificidad, una medida del peso del selector. Se calcula contando tres categorías, que puedes imaginar como un número de tres columnas (A, B, C):

Categoría Cuenta Peso
id (#cabecera) nº de ids 100
clase / atributo / pseudo-clase (.aviso, [type], :hover) nº de ellos 10
elemento / pseudo-elemento (div, ::before) nº de ellos 1

El selector universal * y los combinadores ( , >, +, ~) no aportan especificidad.

Ejemplos comparados

/* especificidad 0,0,1  → 1 */
p { color: black; }

/* especificidad 0,1,1  → 11 */
p.destacado { color: green; }

/* especificidad 0,1,0  → 10 */
.destacado { color: blue; }

/* especificidad 1,0,0  → 100 */
#aviso { color: red; }

Sobre un <p class="destacado" id="aviso">, ganaría #aviso (100) porque el id pesa más que cualquier combinación de clases o elementos. Y entre p.destacado (11) y .destacado (10), gana p.destacado por ser más específico, aunque .destacado se declare después.

La comparación es categoría a categoría, de izquierda a derecha: una sola id vence a cualquier número de clases, y una sola clase vence a cualquier número de elementos. Por eso 10 clases (0,10,0) no superan a un id (1,0,0).

⚠️ TRAMPA CLÁSICA: id pisa a clase, y clase pisa a etiqueta, sin importar el orden. Imagina un menú con .enlace { color: gray } para el estado normal y #menu a { color: tomato } para resaltarlo: el id manda y los enlaces salen naranjas, aunque la clase esté escrita después. No es magia ni un fallo del navegador; es la columna de la izquierda mandando sobre la de la derecha. Cuando una regla "no funciona", lo primero que debes preguntarte es qué otra la supera en especificidad.

!important: el último recurso

Añadir !important a una declaración la saca de la competición normal de especificidad y la coloca por encima:

.boton { color: blue !important; }
#cabecera .boton { color: red; }   /* pierde: el !important gana */

Funciona, y por eso engancha: cuando algo "no se aplica", soltar un !important lo arregla al instante. El problema es que es pan para hoy y hambre para mañana, una mala práctica salvo casos muy puntuales:

La buena práctica es mantener la especificidad baja y uniforme (apóyate en clases, evita los ids para estilar y no anides selectores en exceso). Así la cascada y el orden de aparición bastan para que gane la regla correcta, y el !important se queda donde debe: como último recurso, no como tu martillo para todo.

Pon esto en práctica

DevPath es un curso práctico: aquí lees la teoría; en la app la pones en práctica con ejercicios que se ejecutan de verdad, sin conexión.

Empezar gratis en la app →
← La cascada y la herenciaVer el módulo →