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á.
- @content: todo lo que agreguemos entre las llaves,
- #{selector}: vuelve a agregar nuestro selector anterior.
- body.modo-oscuro: la clase que va a ser responsable por nuestros estilos de modo oscuro.
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!