La regla `@layer` es una de las novedades más útiles de CSS moderno para organizar y controlar el css en en proyectos grandes. Permite definir capas (layers) de estilos, facilitando la gestión de prioridades y evitando conflictos entre componentes, utilidades y estilos globales. En este post te explico cómo la estoy usando en mi sitio web y por qué puede mejorar la mantenibilidad de tus hojas de estilo. --- ## ¿Qué es `@layer` en CSS? `@layer` permite agrupar reglas CSS en capas nombradas. Así puedes decidir qué estilos tienen prioridad sobre otros, sin depender solo del orden de importación o la especificidad. Por ejemplo, puedes tener una capa para utilidades, otra para componentes y otra para estilos globales: ```css @layer global, utilities, components; @layer utilities { .text-center { text-align: center; } } @layer components { .card { border-radius: 1rem; box-shadow: 0 2px 8px #0002; } } @layer global { body { font-family: system-ui, sans-serif; } } ``` Aqui podemos ver como la primera capa `global` define estilos que se aplican a todo el sitio, mientras que `utilities` y `components` definen estilos más específicos. Si hay conflictos, la capa definida después tiene prioridad. --- ## Ejemplo real: grid.css En mi proyecto, uso `@layer grid` para encapsular la lógica de mi sistema de grillas: ```css @layer grid { .content-grid { --padding-inline: 1rem; --content-max-width: 1140px; --breakout-max-width: 1440px; --breakout-size: calc( (var(--breakout-max-width) - var(--content-max-width)) / 2 ); display: grid; grid-template-columns: [full-width-start] minmax(var(--padding-inline), 1fr) [breakout-start] minmax(0, var(--breakout-size)) [content-start] min( 100% - (var(--padding-inline) * 2), var(--content-max-width) ) [content-end] minmax(0, var(--breakout-size)) [breakout-end] minmax(var(--padding-inline), 1fr) [full-width-end]; } .content-grid > :not(.breakout, .full-width), .full-width > :not(.breakout, .full-width) { grid-column: content; } .content-grid > .breakout { grid-column: breakout; } .content-grid > .full-width { grid-column: full-width; display: grid; grid-template-columns: inherit; } } ``` Esto me permite aislar la lógica de grillas y asegurar que no interfiera con otros estilos del proyecto. ## Puntos importantes al usar `@layer` Al utilizar `@layer`, normalmente debes tener una definición inicial de como están ordenadas estas capas, por ejemplo: ```css @layer reset, base, components, utilities; ``` Esto define un orden de cascada claro: - `reset`: Estilos de reinicio para normalizar el CSS. - `base`: Estilos base como tipografía y colores. - `components`: Estilos para componentes específicos. - `utilities`: Utilidades de estilo que pueden aplicarse en cualquier parte. Esto asegura que los estilos se apliquen en el orden correcto, evitando sorpresas. Y en cualquier momento que necesites agregar estilos a estas capas, puedes hacerlo de forma sencilla: ```css @layer utilities { .text-bold { font-weight: bold; } } ``` Otra cosa importante al utilizar `@layer` es que puedes importar capas desde archivos externos, lo que te permite mantener tu CSS modular y organizado: ```css @import "reset.css" layer(reset); @import "base.css" layer(base); @import "components.css" layer(components); @import "utilities.css" layer(utilities); ``` Ademas de esto tambien es importante entender como funcionan los !important con estas capas. Si bien `@layer` ayuda a organizar y controlar la cascada, los estilos marcados con `!important` dentro de una capa aún tendrán prioridad sobre los estilos normales, independientemente de la capa en la que se encuentren. Esto debido a que `!important` aumenta la especificidad de una regla, haciendo que se aplique por encima de otras reglas, incluso si estas están en capas posteriores. Un ejemplo de esto sería: ```css @layer utilities { .text-bold { font-weight: bold !important; } } @layer components { .text-bold { font-weight: normal; } } ``` En este caso, `.text-bold` siempre será negrita debido al `!important`, independientemente de que esté en una capa posterior. ## Un detalle avanzado: `@property` y `@layer` Es común preguntarse si podemos encapsular definiciones de variables usando `@property` dentro de una capa para hacerlas "privadas" o scoped. La respuesta es: **Sí puedes escribirlo dentro, pero NO se hace privado.** ```css @layer components { @property --card-bg { syntax: ""; initial-value: #fff; inherits: false; } } ``` Aunque esto es sintácticamente válido y excelente para mantener tu código organizado (manteniendo la definición cerca de su uso), la regla `@property` **siempre es global**. No importa en qué capa la definas, el registro de la variable ocurre para todo el documento. Sin embargo, **los valores** que asignes a esa variable sí respetan las capas: ```css @layer base { :root { --card-bg: blue; } } @layer components { :root { --card-bg: red; } /* Gana porque 'components' tiene mayor prioridad */ } ``` Por lo tanto: úsalo dentro de layers para organizar tu código, pero recuerda que el nombre de la propiedad (`--card-bg`) sigue ocupando el espacio global. --- ## Ventajas de usar `@layer` - **Organización:** Agrupa estilos relacionados, facilitando la lectura y mantenimiento del código. - **Prioridad clara:** Define explícitamente qué estilos deben aplicarse primero, evitando conflictos. - **Modularidad:** Permite dividir el CSS en archivos separados por capas, mejorando la estructura del proyecto. - **Compatibilidad:** Funciona bien con herramientas modernas de construcción y preprocesamiento de CSS. - **Facilidad de colaboración:** Permite a múltiples desarrolladores trabajar en diferentes capas sin interferir entre sí. - **Mejora la mantenibilidad:** Al tener capas bien definidas, es más fácil identificar y modificar estilos específicos sin afectar el resto del proyecto. --- ## Conclusión Adoptar `@layer` en tus hojas de estilo te ayuda a mantener el orden y la claridad en proyectos modernos. Es especialmente útil cuando trabajas con utilidades, frameworks o múltiples colaboradores. Te animo a probarlo y experimentar cómo mejora la organización de tu CSS. ¿Ya lo usaste? ¡Pronto agregaré un chat para que compartas tu experiencia! Si tienes preguntas o quieres compartir cómo lo estás usando, ¡déjame un comentario en este post en Linkedin!