css props and layers examples
css props and layers examples

Organiza Estilos en CSS con @layer Eficazmente

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:


@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:

@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:

@layer reset, base, components, utilities;

Esto define un orden de cascada claro:

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:

@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:

@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:

@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.

@layer components {
  @property --card-bg {
    syntax: "<color>";
    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:

@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


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!

¡Link copiado!

Comments for LYRCSS