En CSS, la cascada es el mecanismo que controla el resultado final cuando se aplican varias declaraciones CSS contradictorias sobre el mismo elemento HTML. Se trata de un concepto esencial en el lenguaje CSS, y de hecho forma parte de sus iniciales: Cascading Style Sheets (hojas de estilo en cascada).
Cuando se carga una página web, el navegador web no aplica los estilos CSS de arriba a abajo, de manera estricta. En su lugar, lo que hace es seguir un proceso más complejo. Para controlar el orden en el que se aplican las declaraciones CSS, se usan los tres conceptos siguientes, en el orden indicado:
Primero se tiene en cuenta el concepto de la importancia, relativo a la ubicación del código. Cuando dos declaraciones CSS tienen la misma importancia, entonces la especificidad de las reglas decidirá la que se aplica. Y si tienen la misma especificidad, el orden de las fuentes controla el resultado.
Más allá de estos tres conceptos fundamentales sobre la cascada, existe la posibilidad de crear «capas de cascada», usadas para crear grupos independientes de especificidad. Las reglas CSS de una capa no afectan directamente a las de otra capa. Se crean mediante la regla arroba @layer
.
La importancia
La importancia de las declaraciones CSS depende de dónde se han especificado. Las declaraciones contrapuestas se aplican en el siguiente orden: las nuevas anulan a las más antiguas.
- Hoja de estilos del agente de usuario.
- Declaraciones normales en hojas de estilo de usuario.
- Declaraciones normales en hojas de estilo de autor.
- Declaraciones importantes en hojas de estilo de autor.
- Declaraciones importantes en hojas de estilo de usuario.
La hoja de estilos del agente de usuario es la que está integrada en el navegador web, por defecto, y tiene el nivel de prioridad más bajo. Cada navegador tiene sus propias reglas sobre cómo mostrar los elementos HTML. Por ejemplo, los enlaces no visitados suelen estar subrayados y de color azul.
La hoja de estilos de usuario es la que ha especificado el usuario con el objetivo de personalizar los estilos. Algunos navegadores web pueden ser incompatibles con las hojas de estilo de usuario, aunque pueden ser muy prácticas para determinados tipos de minusvalía, como la dislexia, facilitando la lectura.
La hoja de estilos de autor es la que ha creado el desarrollador web, por lo que se encuentra vinculada de alguna manera al documento HTML, o forma parte del mismo. Se trata de la hoja de estilos de mayor importancia.
Hay dos tipos de hojas de usuario y de autor: las que contienen declaraciones CSS normales y las que contienen declaraciones CSS importantes. ¿Cuál es la diferencia entre las unas y las otras? ¿Cómo se definen las importantes?
Las declaraciones normales no tienen tanta prioridad como las declaraciones importantes. Estas últimas tienen la particularidad de que el valor termina con la expresión !important
. De este modo se incrementa la importancia —valga la redundancia— de las declaraciones. Dicho de otro modo, las declaraciones importantes anulan las declaraciones de menor importancia.
Por lo tanto, las declaraciones importantes en hojas de estilo de usuario son las que tienen la prioridad más alta. Esto significa que se sobrepondrán a lo que haya especificado el diseñador web, y por supuesto, estarán también por encima de lo que tenga establecido el navegador web.
La especificidad
La especificidad tiene que ver con lo específico que sea un selector de una regla CSS. Un selector de especificidad baja puede dar como resultado muchos elementos; por ejemplo, el asterisco (*
) selecciona a todos los elementos del documento. En cambio, un selector con una especificidad alta será más preciso; por ejemplo, un identificador (#id
) sólo tendrá un resultado.
Por lo tanto, si la importancia no elimina la ambigüedad, se pasa a determinar la especificidad de los selectores CSS. Se trata de un criterio muy importante a la hora de trabajar en CSS, ya que comprender bien la cascada es crucial. No obstante, el concepto de la especificidad es bastante desconocido.
El concepto de cascada puede resultar demasiado avanzado para usuarios que no conozcan bien el tema de los selectores. Si es el caso, se recomienda la lectura sobre los selectores como requisito previo.
Si dos o más declaraciones entran en contradicción por un elemento determinado y todas las declaraciones tienen la misma importancia, ganará la declaración que tenga la regla con el selector más específico.
Calcular la especificidad de un selector
Es posible calcular la especificidad de un selector de forma fácil. Se determina partiendo de un cálculo matemático basado en cuatro componentes: “A”, “B”, “C” y “D”. El componente “A” es el más distintivo y el “D”, el que menos. En la tabla siguiente se describen los cuatro componentes:
Componente | Descripción |
---|---|
A | Estilos insertados usando el atributo style . Si la declaración existe mediante este atributo, el valor es 1, si no, es 0. |
B | Equivale al número de veces que aparece un identificador (empiezan con # ) en el selector. |
C | Equivale al número de veces que aparece una clase (empiezan con . ), una pseudoclase (como :hover ) o un atributo (como [type="radio"] ) en el selector. |
D | Equivale al número de veces que aparece un elemento o un pseudoelemento (como ::before o ::after ) en el selector. |
Ahora, para conseguir la especificidad de cualquier regla CSS se trata de unir estos cuatro componentes. Vamos a ver una tabla con algunos ejemplos:
Selector | A | B | C | D | Especificidad |
---|---|---|---|---|---|
Atributo style (sin selector) | 1 | 0 | 0 | 0 | 1, 0, 0, 0 |
#ejemplo | 0 | 1 | 0 | 0 | 0, 1, 0, 0 |
.clase | 0 | 0 | 1 | 0 | 0, 0, 1, 0 |
h1 | 0 | 0 | 0 | 1 | 0, 0, 0, 1 |
#menu div ul li .ab .cd | 0 | 1 | 2 | 3 | 0, 1, 2, 3 |
Los valores de los cuatro componentes tienen la misma notación posicional que se usa en matemáticas. Esto significa que el componente A equivale a millares, el componente B equivale a las centenas, el componente C equivale a las decenas y el componente D equivale a las unidades.
En este sentido, y comparando los ejemplos, podemos ver que 1000 es mayor que 100, que 10, que 1 y que 123, por lo tanto tiene la mayor especificidad. También podemos ver que 123 es mayor que 100, que 10 y que 1.
Las declaraciones insertadas mediante el atributo style
, al no tener selector, su especificidad siempre será 1, 0, 0, 0
, es decir, 1000.
Vamos a comentar el último ejemplo con más detalle. Se trata del siguiente selector: #menu div ul li .ab .cd
, en el que podemos ver que tiene un identificador, tres elementos y dos clases. Su especificidad es 0, 1, 2, 3
(123).
Calculemos A, B, C y D. Primero, A=0 porque es un selector, no se trata de una declaración con el atributo style
. Hay un selector de identificador (#menu
), por tanto B=1. Hay dos selectores de clase (.ab
y .cd
), por tanto C=2. Finalmente, hay tres selectores de elemento (div
, ul
y li
), por lo que D=3. Unificando los valores obtenidos de A (0), B (1), C (2) y D (3) obtenemos 123.
Hay que mencionar que algunos elementos de selectores que permiten realizar todo tipo de combinaciones, como +
, >
, ~
, el espacio en blanco y la pseudoclase de negación (:not()
) no afectan a la especificidad de un selector. Tampoco afecta el selector universal (*
). Sin embargo, sí que afectan los selectores que se encuentren declarados dentro de :not()
.
El orden
Cuando dos declaraciones CSS están aplicadas al mismo elemento, tienen la misma importancia y la misma especificidad, la prioridad final se decide a partir del orden en el que se encuentre la regla CSS.
Si se trata de una hoja de estilos externa, las declaraciones que se encuentren al final del archivo CSS anularán a las que se encuentren en declaradas en líneas anteriores. Si se encuentran en diferentes hojas de estilos externas, tendrá preferencia la última que se ha declarado.