Dark Mode con Animaciones en CSS y JavaScript

Curso de Transformaciones y Transiciones en CSS

Take the first classes for free

SHARE THIS ARTICLE AND SHOW WHAT YOU LEARNED

¡Te doy la bienvenida a un nuevo reto de CSS! Esta vez vamos a hacer un Toggle Button para cambiar de Light Mode a Dark Mode usando animaciones de CSS y JavaScript.

Compártenos el resultado final en los comentarios y/o en Twitter con el hashtag #RetosPlatziCSS. 😉

0

Antes de comenzar, los cursos de Platzi que te recomiendo para realizar este reto son los siguientes:

Paso 0: planeación

Para este reto te propongo que realices los siguientes 4 pasos:

  1. Crea los estilos base de tu toggle button
  2. Añade JavaScript para crear el movimiento
  3. ¡Pon a prueba tu creatividad! ¡Estiliza tu toggle button!
  4. ¡Compártenos tu resultado en los comentarios!

💡 Recomendación: Evita copiar y pegar el código. Trata de transcribir cada detalle y entender muy bien su funcionamiento (sin afán, tómate tu tiempo). Solo de esta forma podrás convertirte en un(a) experto(a) en maquetación con CSS.

ʕ•́ᴥ•̀ʔっ ¡Empecemos!

Paso 1: crea los estilos base de tu toggle button

Lo primero que tenemos que tener en cuenta es que nuestro botón en realidad será un input de tipo checkbox que nos permitirá hacer el switch entre el modo claro y el modo oscuro. También tendremos un label que estilizaremos a nuestro gusto.

En primera instancia, pensemos que la base fundamental de nuestro toggle button para el modo claro debe verse de la siguiente manera:

1

Y para el modo oscuro debe verse de esta otra forma:

2

Teniendo en cuenta lo anterior, esta es la paleta de colores que en nuestro CSS se vería de la siguiente forma:

:root {
  --light-0: #f8f9fa;
  --light-1: #e9ecef;
  --light-2: #dee2e6;
  --dark-0: #495057;
  --dark-1: #343a40;
  --dark-2: #212529;
}

💡 Tutorial: variables nativas en CSS

Ahora debemos escribir el HTML que nos permitirá tener el input, el label y el div para la bolita del centro:

<input id="toggle-button" type="checkbox">
<label for="toggle-button">
  <div class="sun-moon"></div>
</label>

Teniendo nuestro HTML podemos escribir los estilos para nuestro body, tanto para el modo claro como para el modo oscuro.

A nuestro body le quitaremos la margen por defecto (margin: 0) y le añadiremos

  • Background claro (background: var(--light-0)).
  • Centrado de elementos (display: grid y place-items: center).
  • Alto de toda la página que esté visualizando el usuario (height: 100vh).
  • Y una transición al background para cuando hagamos el switch entre el modo claro y oscuro (para que no se vea tan tosco) (transition: background 0.3s ease).
body {
  background: var(--light-0);
  display: grid;
  height: 100vh;
  margin: 0;
  place-items: center;
  transition: background 0.3s ease;
}

A nuestro body también le añadiremos una clase llamada dark que nos permitirá cambiar el background a partir de JavaScript más adelante:

body.dark {
  background: var(--dark-2);
}

Con nuestro body listo comenzamos a estilizar nuestro label para el modo claro. Debemos añadir una posición relativa (position: relative) para que nuestro input se pueda ocultar detrás de él (con position: absolute), también añadimos un background para el modo claro (background: var(--light-2)), un borde redondeado (border-radius: 20px), una manita en el cursor que indique que podemos hacer click allí (cursor: pointer), un alto (height: 38px) y un ancho (width: 68px):

input {
  position: absolute;
}

label {
  background: var(--light-2);
  border-radius: 20px;
  cursor: pointer;
  height: 38px;
  position: relative;
  width: 68px;
}

Y para el modo oscuro del label debemos decirle al input que cuando esté checkeado (#toggle-button:checked) cambie el background de su hermano (+ label):

#toggle-button:checked + label {
  background: var(--dark-0);
}

Ahora podemos crear los estilos para la bolita del centro. Yo voy a añadir un color de fondo (background: var(--light-1)), un ancho (width: 30px) y un alto (height: 30px) con las mismas dimensiones, un redondeado para hacer la forma de un círculo (border-radius: 50%), un margen para que no quede tan cerca a los bordes del label (margin: 4px) y finalmente una transición a la transformación (que hará que se desplace de izquierda a derecha) para cuando hagamos el switch entre el modo claro y oscuro y no se vea tan tosco (transition: transform 0.3s ease):

label .sun-moon {
  background: var(--light-1);
  border-radius: 50%;
  height: 30px;
  margin: 4px;
  transition: transform 0.3s ease;
  width: 30px;
}

Para el modo oscuro de la bolita debemos decirle al input que cuando esté checkeado (#toggle-button:checked) cambie el background (background: var(--dark-1)) y le añada una transformación (transform: translateX(30px)) del hijo de su hermano (+ label .sun-moon):

#toggle-button:checked + label .sun-moon {
  background: var(--dark-1);
  transform: translateX(30px);
}

Paso 2: añade JavaScript para crear el movimiento

Una vez que tenemos los estilos de nuestro toggle button, debemos decirle desde JavaScript que añada la clase dark al body una vez nuestro input este checkeado para obtener el siguiente efecto:

3

Para eso debemos acceder al DOM de la siguiente forma:

const toggleButton = document.getElementById('toggle-button')

Luego le decimos que escuche cuando se haga un cambio en el toggle buttton (es decir, cada vez que se le haga click):

toggleButton.addEventListener('change', () => {
  // Ahorita ponemos código aquí :)
})

Finalmente, cada que suceda ese cambio le agregamos la clase dark solo cuando esté activo el input:

toggleButton.addEventListener('change', () => {
  document.body.classList.toggle('dark')
})

Paso 3: ¡pon a prueba tu creatividad! Estiliza tu toggle button

En este paso quiero que seas muy libre y añadas el estilo que más te guste. Para eso, aquí te comparto varios ejemplos de la comunidad de CodePen para que te inspires:

En mi caso, quise agregar unos GIF’s de fondo, así:

0

Para lograrlo añadí dos colores más (--green y --blue):

:root {
  --light-0: #f8f9fa;
  --light-1: #e9ecef;
  --light-2: #dee2e6;
  --dark-0: #495057;
  --dark-1: #343a40;
  --dark-2: #212529;
  --green: #c3c82c;
  --blue: #2939ff;
}

También hice modificaciones a los backgrounds quitándoles los colores planos y añadiendo los GIFs:

label {
  align-items: center;
  background: var(--light-2);
  background: url('https://i.ibb.co/ZWmbGbj/etmfdr.gif');
  background-position: bottom;
  background-size: cover;
  border-radius: 35px;
  box-shadow: 0 19px 38px rgba(0,0,0,0.30), 0 15px 12px rgba(0,0,0,0.22);
  cursor: pointer;
  display: flex;
  height: 60px;
  position: relative;
  width: 110px;
}

#toggle-button:checked + label {
  background: var(--dark-0);
  background: url('https://i.pinimg.com/originals/94/ff/74/94ff7463a1574221ba6d4ada2c997e0b.gif');
  background-position: center;
  background-size: cover;
}

label .sun-moon {
  background: radial-gradient(var(--green), transparent);
  border-radius: 50%;
  height: 30px;
  margin: 4px;
  transition: transform 0.3s ease;
  width: 30px;
}

#toggle-button:checked + label .sun-moon {
  background: radial-gradient(var(--blue), transparent);
  transform: translateX(72px);
}

Paso 4: ¡Compártenos tu resultado en los comentarios!

¡Este paso es mi favorito! Compártenos en los comentarios y/o en Twitter con el hashtag #RetosPlatziCSS el resultado final de tu toggle de light a dark mode. 😄

Aquí te comparto mi codepen, mi repositorio de GitHub y el deploy con el resultado final.

¡Cuéntanos qué otro tipo de retos te gustaría encontrar en esta sección!

#NuncaParesDeAprender

Curso de Transformaciones y Transiciones en CSS

Take the first classes for free

SHARE THIS ARTICLE AND SHOW WHAT YOU LEARNED

0 Comments

to write your comment

Related articles