CSS: Estilos en cascada

En esta lección se comenta el mecanismo de cascada definida en la futura recomendación CSS Cascading and Inheritance Level 4. Aunque actualmente (marzo de 2023) esta recomendación no está formalmente aprobada, se considera parte de la definición oficial de CSS en CSS Snapshot 2023.

Por qué se llaman estilos en cascada

Las hojas de estilo se llaman hojas de estilo "en cascada" porque:

Si las propiedades (escritas en diferentes sitios o para diferentes elementos) no entran en conflicto, el navegador aplica todas las propiedades. Por ejemplo, si el color de fondo de un elemento está definido en un sitio y el tamaño de letra en otro sitio, el navegador aplicará ambas propiedades al elemento.

Pero si las propiedades entran en conflicto (por ejemplo, el color del fondo del elemento está definido en varios sitios con colores distintos), existen reglas para decidir qué propiedad tiene preferencia.

Dónde pueden aparecer las propiedades de estilo

Las propiedades de estilo pueden aparecer en tres lugares distintos:

Reglas de aplicación de los estilos

Si se define la misma propiedad para la misma etiqueta con el mismo selector en dos sitios distintos, las reglas de precedencia son las siguientes:

Además de estas propiedades definidas por el creador de la página web, hay que tener en cuenta que también se aplican las propiedades definidas en la hoja de estilo por defecto del navegador.

Si las propiedades se encuentran definidas en diferentes hojas de estilo, el navegador aplica el valor definido en la última hoja de estilo enlazada (es decir, en el último enlace <link> del <head>).

Elementos dentro de otros

Cuando un elemento está contenido en otro (por ejemplo, un párrafo <p> dentro de una división <div>), al elemento de dentro se le aplican también las propiedades definidas para el elemento de fuera.

En el ejemplo siguiente, el párrafo incluido dentro de la división se muestra de color rojo porque el párrafo está incluido dentro de la división.

<div>
  <p>Esto es un párrafo dentro de una división.</p>
</div>
div {
  border: black 3px solid; color: red;
}
Enlace externo

Si una misma propiedad está definida para el elemento inferior y para el superior, se aplica el valor establecido para el elemento inferior.

En el ejemplo siguiente, el párrafo se muestra de color negro, independientemente del orden en que se escriban las reglas.

div {
  border: black 3px solid;
  color: red;
}

p {
  color: black;
}
Enlace externo
p {
  color: black;
}

div {
  border: black 3px solid;
  color: red;
}
Enlace externo

Reglas distintas que se aplican al mismo elemento

Dos reglas distintas se aplican a un mismo elemento cuando el elemento coincide con los selectores de ambas reglas. La regla que se aplica es la del selector de mayor especificidad. La especificidad de un selector se calcula atendiendo a los siguientes criterios:

  1. Número de atributos id en el selector
  2. Número de otros atributos y pseudo-clases en el selector (los pseudo-elementos se ignoran)
  3. Número de elementos en el selector
  4. Posición en la hoja de estilo

Estos criterios se aplican en orden, es decir, primero se comparan el número de atributos id de cada selector. Si un selector tiene más que el otro, se aplica esa regla, si el número es el mismo, entonces se calcula el segundo criterio (número de otros atributos y pseudo-clases). Y así sucesivamente.

A continuación se muestran varios ejemplos de aplicación de estas reglas.

Número de atributos id en el selector

El ejemplo siguiente muestra dos selectores con un número de atributos id diferente (1 o 0). Puede comprobarse que se aplica siempre el selector con atributo id, independientemente del orden en que aparezcan en la hoja de estilo.

<p id="nuevo">Esto es un párrafo con atributo id "nuevo"</p>

<p>Esto es un párrafo sin atributo id.</p>
p#nuevo {
  color: red;
}

p {
  color: black;
}
Enlace externo
p {
  color: black;
}

p#nuevo {
  color: red;
}
Enlace externo

El ejemplo siguiente muestra también dos selectores con un número de atributos id diferente (2 o 1). Puede comprobarse que se aplica siempre el selector con más atributos id, independientemente del orden en que aparezcan en la hoja de estilo.

div#viejo {
  border: black 3px solid;
  margin: 2px;
  padding: 2px;
}

div p#nuevo {
  color: red;
}

div#viejo p#nuevo {
  color: black;
}
Enlace externo
div#viejo {
  border: black 3px solid;
  margin: 2px;
  padding: 2px;
}

div#viejo p#nuevo {
  color: black;
}

div p#nuevo {
  color: red;
}
Enlace externo

Número de otros atributos y pseudo-clases en el selector

El ejemplo siguiente muestra dos selectores con el mismo número de atributos id (0), pero con un número diferente de atributos class (1 o 0). Puede comprobarse que se aplica siempre el selector con más atributos class, independientemente del orden en que aparezcan en la hoja de estilo.

div.viejo {
  border: black 3px solid;
  margin: 2px;
  padding: 2px;
}

div.viejo p {
  color: red;
}

div p {
  color: black;
}
Enlace externo
div.viejo {
  border: black 3px solid;
  margin: 2px;
  padding: 2px;
}

div p {
  color: black;
}

div.viejo p {
  color: red;
}
Enlace externo

Número de elementos en el selector

El ejemplo siguiente muestra dos selectores con un número diferente de elementos (2 o 1). Puede comprobarse que se aplica siempre el selector con más elementos, independientemente del orden en que aparezcan en la hoja de estilo.

div {
  border: black 3px solid;
  margin: 2px;
  padding: 2px;
}

div p {
  color: red;
}

p {
  color: black;
}
Enlace externo
div {
  border: black 3px solid;
  margin: 2px;
  padding: 2px;
}

p {
  color: black;
}

div p {
  color: red;
}
Enlace externo

El ejemplo siguiente también muestra dos selectores con un número diferente de elementos (2 o 1). Puede comprobarse que se aplica siempre el selector con más elementos, independientemente del orden en que aparezcan en la hoja de estilo.

li {
  color: black;
}

ul li {
  color: red;
}
Enlace externo
ul li {
  color: red;
}

li {
  color: black;
}
Enlace externo

El ejemplo siguiente también muestra dos selectores con un número diferente de elementos (1 o 0). Puede comprobarse que se aplica siempre el selector con más elementos, independientemente del orden en que aparezcan en la hoja de estilo.

p.nuevo {
  color: black;
}

.nuevo {
  color: red;
}
Enlace externo
.nuevo {
  color: red;
}

p.nuevo {
  color: black;
}
Enlace externo

Posición en la hoja de estilo

Si a un elemento le afectan dos selectores con la misma especificidad, el navegador aplica la propiedad que aparece después en la hoja de estilo.

El ejemplo siguiente muestra dos selectores idénticos. Puede comprobarse que se aplica siempre el selector que aparece después en la hoja de estilo. En este caso, la penúltima regla es superflua y puede eliminarse sin afectar al resultado.

div {
  border: black 3px solid;
}

div p {
  color: red;
}

div p {
  color: black;
}
Enlace externo
div {
  border: black 3px solid;
}

div p {
  color: black;
}

div p {
  color: red;
}
Enlace externo

El ejemplo siguiente muestra una situación diferente y más habitual. Se trata de un párrafo con dos clases. Puede comprobarse que se aplica siempre el selector que aparece después en la hoja de estilo.

p.viejo {
  color: red;
}

p.nuevo {
  color: black;
}
Enlace externo
p.nuevo {
  color: black;
}

p.viejo {
  color: red;
}
Enlace externo