Lucas Terracino
Mates && Code

Follow

Mates && Code

Follow
Haciendo temas fácilmente con mixins de SASS

Haciendo temas fácilmente con mixins de SASS

Lucas Terracino's photo
Lucas Terracino
·Oct 23, 2020·

3 min read

Mientras desarrollaba el modo modo oscuro en una App de React, me encontré escapándole al anidado de Sass una y otra vez parar armar los estilos oscuros. Y justo ahí, nació este mixin.

Veamos el código

@mixin enModoOscuro {
    $selector: #{&};
    @at-root body.modo-oscuro #{$selector} {
        @content
    }
}

Es importante mencionar que esto va a funcionar en cualquier tipo de proyecto que use Sass. Y se que los Styled Components pueden completar el hacer temas fácilmente también, pero me gusta mucho Scss y tener a mis componentes con sus propios archivos de estilo.

Análisis

Cuando el modo oscuro está habilitado, <body> recibe la clase modo-oscuro. Y para anteponer body.modo-oscuro al selector, el mixin funciona así:

  • $selector: parsea nuestro selector actual haciendo uso de **& (selector de padre)** y #{}, luego lo almacena en la variable.
  • @at-root: mueve el siguiente selector a la raíz del documento, escapando el anidado actual.
    • body.modo-oscuro: la clase que va a ser responsable por nuestros estilos de modo oscuro.
      • #{selector}: vuelve a agregar nuestro selector anterior.
        • @content: todo lo que agreguemos entre las llaves, {} en nuestro **include** va acá.

Uso

.solo-una-caja {
    background: white; // ☀
    color: black; // ☀
    width: 100px;
    height: 100px;
    // Dark Theme styles
    @include enModoOscuro {
        background: black; // 🌙
        color: white; // 🌙
    }
}

Después de compilar el código a CSS se va a ver así:

.solo-una-caja {
    background: white;
    color: black;
    width: 100px;
    height: 100px;
}
body.modo-oscuro.solo-una-caja {
    background: black;
    color: white;
}

🧬 Evolucionando el mixin: Múltiples temas

¿Por qué conformarnos con modo oscuro? Creemos muchos temas con ¡un solo mixin para gobernarlos a todos!

@mixin enTema($tema: "default") {
    $selector: #{&};
    @at-root body.tema-#{$tema} #{$selector} {
        @content
    }
}

Uso

Ahora podemos pasarle un argumento a nuestro mixin y agregar estilos dinámicamente a los temas que creemos.

.navegacion {
    background: white;
    color: black;
    width: 100%;
    height: 52px;
    // Estilos de Temas
    @include enTema("rojo") {
        background: red; // 🟥
    }
    @include enTema("verde") {
        background: green; // 🟩
    }
    @include enTema("azul") {
        background: blue; // 🟦
    }
    @include enTema("halloween") {
        background: purple; // 👻
    }
}

Después de compilar el código a CSS se va a ver así:

.navegacion {
    background: white;
    color: black;
    width: 100%;
    height: 52px;
}

body.tema-rojo .navegacion {
    background: red;
}

body.tema-azul .navegacion {
    background: blue;
}

body.tema-verde .navegacion {
    background: green;
}

body.tema-halloween .navegacion {
    background: purple;
}

💡Algunas ideas

Para mantener el post conciso y simple, dejo un par de ideas que pueden agregar a su proyecto para mejorar lo visto hasta acá.

  • Variables de CSS
  • Una variable como $temas con valores predefinidos para chequear que el argumento que se pasa al mixin enTema sea válido.
  • Modo oscuro "Automático" con la regla de CSS filter: invert().

Conclusión

Usando la directiva de SASS @at-root en nuestros mixins vamos a ahorrar mucho tiempo, creando selectores específicos para nuestros temas con gran facilidad, apoyándonos en la poderosa especificidad de CSS.

Si el post fue de ayuda o crees ves algo que pueda mejorar ¡dejame un comentario más abajo!

¡Hasta la próxima 👋!

English version!

 
Share this