CSS: Cascada

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, incluso forma parte de sus iniciales: Cascading Style Sheets (hojas de estilo en cascada).

Para controlar el orden en el que se aplican las declaraciones CSS, se usan los tres conceptos siguientes (por orden):

  1. Importancia.
  2. Especificidad.
  3. Orden.

El concepto prioritario es la importancia, como es de esperar. Pero si dos declaraciones CSS tienen la misma importancia, se usará la especificidad de las reglas para decidir cuál aplicar. Y si tienen la misma especificidad, el que controla el resultado es el orden de las fuentes.

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.

  1. Hoja de estilos del agente de usuario.
  2. Declaraciones normales en hojas de estilo de usuario.
  3. Declaraciones normales en hojas de estilo de autor.
  4. Declaraciones importantes en hojas de estilo de autor.
  5. Declaraciones importantes en hojas de estilo de usuario.

La hoja de estilos del agente de usuario es la que está integrada en el navegador 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.

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.

Tal y como se puede apreciar, 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 1.000 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, 1.000.

Vamos a comentar el último ejemplo con más detalle. 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. En resumen, la especificidad es 0, 1, 2, 3.

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.

← Artículo anterior
CSS: Herencia
Artículo siguiente →
CSS: Selectores