Mixins en SASS

Este artículo explica los mixins en SASS.

Explicaremos los mixins en SASS con ejemplos prácticos.

YouTube Video

Mixins en SASS

Visión general – ¿Qué es un Mixin?

Los mixins son un mecanismo que te permite definir conjuntos de propiedades de estilo comúnmente usadas como funciones reutilizables, las cuales puedes llamar donde lo necesites. Son muy útiles para mantener tus clases CSS y varias propiedades siguiendo el principio DRY (Don't Repeat Yourself, No te repitas).

Ejemplo: El mixin más simple

A continuación hay un ejemplo sencillo de un mixin que reutiliza border-radius y box-shadow juntos. Al llamar a este mixin, puedes aplicar la misma apariencia a varios elementos.

 1// Simple mixin that applies border-radius and box-shadow
 2@mixin card-style {
 3  border-radius: 8px;
 4  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.12);
 5  background: #fff;
 6}
 7
 8.card {
 9  @include card-style;
10  padding: 1rem;
11}
  • Con este mixin, ya no necesitas repetir los estilos directamente.
  • Llamarlo solo requiere una línea: @include card-style;.

Mixins con argumentos (parámetros)

Los mixins pueden aceptar argumentos, igual que las funciones. Esto te permite cambiar la apariencia con la misma lógica. A continuación, un ejemplo donde se toma el color como argumento.

 1// Mixin with parameters: accepts a color and optional radius
 2@mixin colored-box($bg-color, $radius: 4px) {
 3  background-color: $bg-color;
 4  border-radius: $radius;
 5  padding: 0.75rem;
 6}
 7
 8.box-primary {
 9  @include colored-box(#007acc);
10}
11
12.box-custom {
13  @include colored-box(#ffcc00, 12px);
14}
  • Al proporcionar un valor por defecto, puedes controlar el comportamiento cuando un argumento es omitido.
  • En este ejemplo, se utiliza el radio por defecto y solo se sobreescribe el color de fondo.

Casos donde se usan argumentos variables (...)

Cuando quieras aceptar múltiples valores, puedes usar argumentos variables ($args...). Esto es útil para generar clases utilitarias o pasar listas de alternativas (fallback).

Es útil cuando necesitas pasar varias familias de fuentes o múltiples valores de sombra.

1// Mixin that accepts variable arguments and forwards them to box-shadow
2@mixin multi-shadow($shadows...) {
3  box-shadow: $shadows;
4}
5
6.panel {
7  @include multi-shadow(0 2px 4px rgba(0,0,0,0.08), 0 8px 16px rgba(0,0,0,0.06));
8}
  • En la llamada, puedes pasar varias sombras separadas por comas.
  • De esta manera, puedes usar el mismo mixin tanto para sombras simples como complejas.

Mixins con @content — Recibiendo un bloque

Con @content, un mixin puede recibir un bloque de estilos desde la llamada. Esto permite que el mixin aporte un contenedor común, mientras que la llamada especifica los detalles internos.

 1// Mixin that sets up a responsive container and yields to caller via @content
 2@mixin responsive-container($max-width: 1200px) {
 3  margin-left: auto;
 4  margin-right: auto;
 5  padding-left: 1rem;
 6  padding-right: 1rem;
 7  max-width: $max-width;
 8
 9  @content; // place where caller's styles are inserted
10}
11
12.header {
13  @include responsive-container(1000px) {
14    display: flex;
15    align-items: center;
16    justify-content: space-between;
17  }
18}
  • En la llamada, puedes añadir un bloque a @include para insertar estilos dentro.
  • Este patrón es útil para contenedores de layout como grids, tarjetas y formularios.

Mixins avanzados utilizando condicionales y bucles

Las estructuras de control como @if y @for pueden usarse dentro de los mixins. Puedes usarlas para automatizar la generación de utilidades y agrupar configuraciones responsivas.

A continuación, un ejemplo de generación automática de clases utilitarias para anchos.

 1@use 'sass:math';
 2
 3// Mixin that generates width utility classes from a list of fractions
 4@mixin generate-widths($fractions) {
 5  @each $name, $fraction in $fractions {
 6    .w-#{$name} {
 7      width: math.percentage($fraction);
 8    }
 9  }
10}
11
12$widths: (
13  '1-4': 0.25,
14  '1-3': 0.3333,
15  '1-2': 0.5,
16  '3-4': 0.75
17);
18
19@include generate-widths($widths);
  • Simplemente pasando un mapa de las fracciones que deseas generar en el lado que llama, puedes generar automáticamente todas las clases utilitarias correspondientes de una sola vez.
  • Usar este enfoque tiene la ventaja de reducir las definiciones de estilos manuales mientras se mantiene la coherencia en el diseño.

Mixins vs Marcadores de posición (%placeholder)

Mientras que los mixins insertan directamente un conjunto de propiedades, los placeholders se utilizan con @extend al heredar estilos. Los mixins pueden generar CSS duplicado en algunos casos, pero @extend puede producir un CSS más compacto en ciertas situaciones.

Al comprender los propósitos y las diferencias en el CSS generado por cada método, podrás elegir el enfoque más óptimo.

 1// Placeholder example (for comparison)
 2%btn-base {
 3  display: inline-block;
 4  padding: 0.5rem 1rem;
 5  border-radius: 4px;
 6}
 7
 8.btn-primary {
 9  @extend %btn-base;
10  background: #007acc;
11  color: #fff;
12}
13
14.btn-secondary {
15  @extend %btn-base;
16  background: #e0e0e0;
17}
  • Cuando utilizas @extend con un placeholder, varios selectores pueden consolidarse en una sola regla, resultando en un CSS más compacto.
  • Por otro lado, dado que los mixins insertan las propiedades directamente donde se necesitan, ofrecen flexibilidad y ayudan a evitar la fusión no intencionada de selectores.

Patrones prácticos comunes (Responsive, prefijos de navegador, etc.)

En la práctica, es útil poner procesamientos comunes como los prefijos de navegador y características responsivas en mixins. A continuación hay un ejemplo que combina propiedades de transform y prefijos. Puedes centralizar el código para la compatibilidad entre navegadores, facilitando el mantenimiento.

 1// Mixin for transform with vendor prefixes
 2@mixin transform($value) {
 3  -webkit-transform: $value;
 4  -ms-transform: $value;
 5  transform: $value;
 6}
 7
 8.icon-rotate {
 9  @include transform(rotate(45deg));
10}
  • Su uso es simple y puedes emplearlo en cualquier lugar, como por ejemplo @include transform(rotate(10deg));.
  • Incluso si los prefijos dejan de ser necesarios en el futuro, el mantenimiento se facilita porque al actualizar el mixin, el cambio se reflejará en toda tu base de código.

Ejemplo práctico: Tarjetas y botones combinados

A continuación se muestra un ejemplo donde los estilos de botón utilizados dentro de la tarjeta se unifican con un mixin, lo que permite cambiarlos según el color del tema.

Esto organiza el patrón comúnmente usado de 'tarjeta + botón' usando mixins.

 1// Simple mixin that applies border-radius and box-shadow
 2@mixin card-style {
 3  border-radius: 8px;
 4  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.12);
 5  background: #fff;
 6}
 7
 8// Mixin for transform with vendor prefixes
 9@mixin transform($value) {
10  -webkit-transform: $value;
11  -ms-transform: $value;
12  transform: $value;
13}
14
15// Button mixin with theme and size parameters
16@mixin btn($bg, $color: #fff, $padding: 0.5rem 1rem) {
17  display: inline-block;
18  padding: $padding;
19  background: $bg;
20  color: $color;
21  border-radius: 6px;
22  text-decoration: none;
23  cursor: pointer;
24  @include transform(translateY(0)); // reuse earlier transform mixin
25}
26
27// Card mixin that accepts inner button styling via @content
28@mixin card($gap: 1rem) {
29  @include card-style; // reuse earlier card-style mixin
30  padding: $gap;
31  @content;
32}
33
34.card-feature {
35  @include card {
36    .title { font-size: 1.125rem; margin-bottom: 0.5rem; }
37    .cta {
38      @include btn(#007acc);
39    }
40  }
41}
42
43.card-warning {
44  @include card {
45    .title { font-weight: bold; }
46    .cta {
47      @include btn(#ff6600);
48    }
49  }
50}
  • Al usar estos mixins, puedes escribir componentes de forma concisa.

Presta atención al rendimiento y al CSS generado

Como los mixins insertan propiedades cada vez que se llaman, el uso excesivo de @include para la misma regla puede hacer que el CSS final sea más grande. Puedes optimizar combinándolos con marcadores de posición y diseño de componentes cuando sea necesario.

Además, las siguientes medidas también son eficaces.

  • Los estilos que se usan con frecuencia deberían convertirse en clases para su reutilización.
  • Los patrones comunes deben agruparse utilizando @content.
  • La generación de utilidades complejas solo debe realizarse durante el tiempo de compilación.

Consejos para facilitar la depuración

Al utilizar mixins, también es importante idear métodos para mejorar la depuración y el mantenimiento. Al utilizar nombres de variables claros y agregar comentarios dentro de los mixins, será más fácil de entender al revisar el código más adelante. Además, si la funcionalidad se vuelve compleja, dividir el mixin en unidades más pequeñas facilitará las pruebas y mejorará el mantenimiento.

Además, habilitar los mapas de origen permite rastrear fácilmente qué mixin generó qué CSS, lo que facilita el aislamiento de problemas.

A continuación se muestra un ejemplo de un mixin fácil de entender con comentarios de documentación.

1// Example: readable mixin with clear param names and comments
2/// Adds a subtle focus ring for accessibility
3/// $color - ring color
4/// $size - thickness of the ring
5@mixin focus-ring($color: #007acc, $size: 2px) {
6  outline: none;
7  box-shadow: 0 0 0 $size rgba(blue($color), 0.15);
8}
  • Tener comentarios de documentación organizados de esta manera facilita la comunicación y comprensión dentro del equipo.
  • Dado que los comentarios de documentación de SASS pueden extraerse automáticamente con herramientas compatibles, también son útiles para generar documentos como guías de estilos.

Resumen

Dado que los mixins te permiten agrupar estilos de uso común para su reutilización, ayudan a reducir la duplicación de código y mejorar el mantenimiento. Además, cuando varios selectores comparten las mismas reglas, considera usar no solo mixins sino también @extend (marcadores de posición). Además, si bien @content permite una separación flexible entre contenedores de layout y contenidos, un uso excesivo de @include puede llevar a un CSS generado demasiado grande, por lo que se recomienda precaución. Es importante aprovechar al máximo los argumentos, valores por defecto y argumentos variables para diseñar mixins que sean genéricos y fáciles de extender.

Puedes seguir el artículo anterior utilizando Visual Studio Code en nuestro canal de YouTube. Por favor, también revisa nuestro canal de YouTube.

YouTube Video