Organiza mejor tus hojas de estilo con CSS Cascade Layers
La escalada de especifidad
Uno de los problemas recurrentes en el mundo de CSS, sobre todo cuando usamos código de terceros, es la especificad de los selectores y lo que ello conlleva. De hecho, no es raro el uso y abuso de !important para resolver conflictos, con los problemas que puede conllevar su uso. Una mejor alternativa consiste en utilizar selectores más específicos, para asegurarnos de que nuestro código tiene la prioridad deseada, pero aunque sea claramente mejor solución, no está libre de problemas. Concretamente, estamos hablando de lo que, haciendo un símil con una escalada armamentística, podríamos denominar una escalada de especificad: donde cada vez necesitamos selectores más específicos para resolver posibles conflictos. Afortunadamente, existe una alternativa mejor: CSS Cascade Layers.
Capas en cascada
La regla @layer nos va a permitir definir estas CSS Cascade Layers, dentro de las cuales podremos colocar código CSS. Además, esta regla también nos permitirá indicar la prioridad de estas capas, de forma que si un selector se encuentra en una capa prioritaria, tendrá preferencia sobre cualquier otro selector (independientemente de su especificad) de otra capa menos prioritaria.
Básicamente, podemos usar la regla @layer de dos formas. La primera es definir una capa detrás de otra en el orden de menor a mayor prioridad. Otra opción es declarar inicialmente todas las capas que vamos a usar, indicando el orden deseado, y después definir cada capa sin importar el orden.
Veamos un sencillo ejemplo:
/* declaramos 3 capas, de la menos importante a la mas importante */
@layer primera, segunda, tercera;
/* ahora definimos cada capa */
@layer tercera {
h1 { color: green; }
p { color: green; }
}
@layer primera {
h1 { color: red; }
p { color: red; }
}
@layer segunda {
h1 { color: blue; }
p { color: blue; }
}
En la primera línea de este ejemplo, estamos declarando 3 capas, con los nombres «primera», «segunda» y «tercera» (obviamente, puedes declarar el número de capas que quieras). Además, estamos indicando el orden de importancia, siendo la capa «primera» la menos importante en caso de conflicto, después la capa «segunda», y finalmente la capa «tercera» es la que tiene mayor prioridad. Por lo que en este (absurdo) ejemplo, los títulos h1 y los párrafos serán de color verde.
Esta primera línea es opcional, si no la indicamos, simplemente el orden vendrá indicando por el orden en el que definimos cada capa. En este ejemplo, primero estamos definiendo la capa «tercera» que será la menos importante, y finalmente la «segunda» que será la más importante. Por lo que si no indicamos la primera línea, el color de los títulos h1 y de los párrafos sería azul.
Así que, lo más recomendable, es indicar esta primera línea para así determinar claramente el orden de cada capa (también es más cómodo hacerlo así para que se vea claramente el orden y para cambiarlo facilmente si es necesario).
Una cosa que también podemos hacer es volver a definir una capa. Esto lo que hará es añadir código CSS a dicha capa. Esto puede resultar útil si queremos definir varias capas en archivos CSS separados.
Ahora bien, ¿que pasa con el código CSS declarado fuera de una capa? Pues por la forma de funcionar del sistema, cualquier código fuera de una capa, tiene la máxima prioridad en caso de conflicto. Así que si decidimos usar este sistema de capas, es importante colocar todo el código CSS dentro de alguna capa.
El uso de !imporant en CSS Cascade Layers
Lo más recomendable, como siempre, es evitar el uso de !important. Pero si haces uso de él, tienes que tener en cuenta que la prioridad de las capas se invierte. Por ejemplo:
/* declaramos 3 capas, de la menos importante a la mas importante */
@layer primera, segunda, tercera;
/* ahora declaramos cada capa */
@layer tercera {
h1 { color: green !important; }
p { color: green; }
}
@layer primera {
h1 { color: red !important; }
p { color: red; }
}
@layer segunda {
h1 { color: blue !important; }
p { color: blue; }
}
Esta vez, los párrafos serán verdes, pero los títulos serán rojos! Es decir, la primera capa declarada tendrá prioridad en caso de conflicto (si usas el !important).
Para que quede más claro, el orden de prioridad (de más a menos) sería el siguiente:
- !important en la capa «primera».
- !important en la capa «segunda».
- !important en la capa «tercera».
- !important en código CSS fuera de cualquier capa.
- Código CSS fuera de cualquier capa.
- Código CSS en la capa «tercera».
- Código CSS en la capa «segunda».
- Código CSS en la capa «primera».
Como organizar las CSS Cascade Layers
La cantidad de capas y su organización depende mucho de como quieras organizar tu código CSS, pero a modo de ejemplo, una posibilidad sería:
@layer reset, defecto, framework, tema, ajustes;
En este ejemplo, primero tendríamos una capa con código CSS para «eliminar» los estilos del navegador. Después, otra capa para unos estilos genéricos por defecto. Después otra capa para los estilos que usemos a modo de «framework». Después otra capa para los estilos del «tema». Y finalmente una capa para «ajustes» específicos.
Usando CSS Cascade Layers nos aseguramos que, por ejemplo, cualquier selector del «reset» no nos dará problemas con un selector de nuestro «tema». Esto nos da un control más fino sobre las prioridades de los selectores, que es de lo que va todo esto de las capas de estilos CSS.
Además, podemos usar la regla @layer para cargar un archivo CSS directamente en una capa.
@import url(reset.css) layer(reset);
Revertir un cambio de estilo dentro de una capa
En CSS es relativamente frecuente (sobre todo dentro de «media queries») que queramos deshacer algún cambio de estilo. Para ello podemos usar el valor «initial» o el valor «revert» para «resetear» la propiedad CSS.
Cuando usamos capas CSS es posible que queramos «resetear» el valor dentro de la propia capa, para ello disponemos del valor «revert-layer«. O dicho de otro modo, es un valor que podemos usar para quitar dentro de una capa un valor a una propiedad CSS (que le habíamos asignado en otra parte de la misma capa), pero sin afectar a otros valores de otras capas.
@media only screen and (max-width: 500px) {
.ejemplo {
/* quitamos el max-width que le hemos puesto en otro lado */
max-width: revert-layer;
}
}
Conclusión
Las CSS Cascade Layers son una poderosa herramienta para gestionar mejor el código CSS en proyectos medianos o grandes. Nos facilita trabajar con código CSS de terceros, y nos ayuda a crear un código más organizado y robusto.
Si te interesa mejora tu código CSS, échale un vistazo al resto de nuestros artículos sobre diseño Web.