En esta página
Especificidad: como CSS decide que estilo gana
Cómo decide CSS que estilo aplicar?
Cuando multiples reglas CSS apuntan al mismo elemento, el navegador necesita un sistema para decidir cual gana. Ese sistema se llama la cascada y se basa en tres factores, evaluados en este orden:
- Origen e importancia (estilos del usuario, del autor, del navegador)
- Especificidad del selector
- Orden de aparicion en el código
Qué es la especificidad?
La especificidad es un valor numérico que el navegador asigna a cada selector CSS. Se representa como una tupla de tres números: (ID, Clase, Elemento).
| Selector | ID | Clase | Elemento | Valor |
|---|---|---|---|---|
p |
0 | 0 | 1 | (0,0,1) |
.card |
0 | 1 | 0 | (0,1,0) |
p.card |
0 | 1 | 1 | (0,1,1) |
#hero |
1 | 0 | 0 | (1,0,0) |
#hero .card p |
1 | 1 | 1 | (1,1,1) |
Cada columna se compara de izquierda a derecha. Un solo ID (1,0,0) supera a cien clases (0,100,0) porque la columna de ID se evalua primero.
Que cuenta como "clase"?
En la columna de clase se suman:
- Selectores de clase (
.card) - Selectores de atributo (
[type="text"]) - Pseudo-clases (
:hover,:focus,:nth-child())
Que cuenta como "elemento"?
En la columna de elemento se suman:
- Selectores de tipo (
div,p,h1) - Pseudo-elementos (
::before,::after,::placeholder)
El selector universal y los combinadores
El selector universal (*), los combinadores (>, +, ~, ) y la pseudo-clase :where() tienen especificidad cero. No suman nada.
/* Ambos tienen especificidad (0, 1, 0) */
.card { color: red; }
*.card { color: blue; } /* Misma especificidad */La pseudo-clase :is() y :not()
A diferencia de :where(), las pseudo-clases :is() y :not() toman la especificidad del argumento más específico que contienen.
/* Especificidad: (1, 0, 0) por el #hero dentro de :is() */
:is(#hero, .card, p) {
color: red;
}La cascada: orden de aparicion
Cuando dos selectores tienen la misma especificidad, gana el que aparece último en el código fuente.
.título { color: blue; }
.título { color: red; } /* Gana: aparece despues */Capas de cascada con @layer
CSS moderno introduce @layer para controlar la prioridad sin depender del orden fisico del código. Las capas declaradas despues tienen mayor prioridad.
@layer base, componentes, utilidades;
@layer base {
.boton { padding: 0.5rem; }
}
@layer utilidades {
.boton { padding: 1rem; } /* Gana por ser capa posterior */
}Estilos inline y !important
Los estilos inline (style="...") superan cualquier selector en la hoja de estilos. Solo !important puede superarlos, pero su uso excesivo dificulta el mantenimiento.
La prioridad completa, de menor a mayor, es:
- Estilos del navegador (user-agent)
- Estilos del autor (tus CSS)
- Estilos del autor con
!important - Estilos inline
- Estilos inline con
!important
Estrategia recomendada
Para mantener CSS predecible:
- Usa clases como base de tus selectores
- Evita IDs para estilos (reservalos para JavaScript o anclas)
- Evita
!importantsalvo para utilidades muy especificas - Usa
@layerpara organizar la prioridad entre base, componentes y utilidades - Mantiene selectores simples: un nivel de clase suele ser suficiente
Ahora que entiendes como CSS resuelve conflictos, en la siguiente leccion exploraremos el box model, la base de todo el layout en CSS.
Práctica
- Calcula la especificidad: Escribe cinco selectores distintos que apunten al mismo elemento y ordenalos de menor a mayor especificidad. Verifica tu calculo abriendo el inspector del navegador.
- Organiza con @layer: Crea tres capas (
base,componentes,utilidades) con@layery define reglas conflictivas en cada una. Comprueba que la capa declarada al final tiene mayor prioridad. - Elimina un !important: Busca un caso donde necesites
!importanty refactoriza los selectores para que el estilo correcto gane solo por especificidad o por orden de cascada.
/* Especificidad: (0, 0, 1) */
p {
color: black;
}
/* Especificidad: (0, 1, 0) */
.mensaje {
color: blue;
}
/* Especificidad: (0, 1, 1) */
p.mensaje {
color: green;
}
/* Especificidad: (1, 0, 0) */
#alerta {
color: red;
}
/* Especificidad: (0, 2, 0) - mayor que (0, 1, 1) */
.contenedor .mensaje {
color: purple;
}
/* Ambos selectores tienen la misma
especificidad: (0, 1, 0) */
.boton {
background-color: blue;
color: white;
}
/* Este gana por orden: esta despues */
.boton {
background-color: green;
}
/* Usar capas para controlar prioridad */
@layer base, componentes, utilidades;
@layer base {
.boton { background: gray; }
}
@layer componentes {
.boton { background: blue; }
}
@layer utilidades {
.boton { background: green; } /* Gana */
}
Inicia sesión para guardar tu progreso