DEV Community

Cover image for Dark theme solo CSS, MediaQuery y también con Javascript
German P
German P

Posted on

1 1

Dark theme solo CSS, MediaQuery y también con Javascript

Code:Github repo
codepen: Con js y css
codepen: solo css

Instalación

Se puede ejecutar desde cualquier server virtual que tengas, no es necesario al 100%

Primero clonar el repositorio e instalar.

git clone https://github.com/205mdp/html-css-js-dark-light-theme.git

yarn add 
Enter fullscreen mode Exit fullscreen mode

Ejecutar

yarn dev
Enter fullscreen mode Exit fullscreen mode

Opción 1 - Solo css

  • Generar variables que se asignaran a los background y colors.

Documentación Variables

/* solo ejemplo de variables */
body {
  /* crear variable  */
  --main-back-color: red;
  /* asignar variable  */
  background-color: var(--main-back-color); 
}
Enter fullscreen mode Exit fullscreen mode
  • Generar media query.
:root {
  --background: white;
  --color: black;
}

/* media query dark  */
@media (prefers-color-scheme: dark) {
  :root {
    --background: black;
    --color: white;
  }
}
Enter fullscreen mode Exit fullscreen mode
  • Conclusión: con este simple paso toma el theme del navegador y lo aplica en la página.

Opción 2 Con Javascript y media query

Detectamos que configuración tiene el sistema.

if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
    // dark mode
    localStorage.setItem('theme', 'dark');
} else {
    localStorage.setItem('theme', 'light');
}
Enter fullscreen mode Exit fullscreen mode

Evento de cambio schema

window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
  event.matches ? enableDarkMode() : disableDarkMode();
});
Enter fullscreen mode Exit fullscreen mode

Opción 3 Con Javascript manualmente por botón.

Se puede hacer agregando una clase al body .dark , .light lo guardamos en el localStorage también.

// cambio de dark mode a ligh mode. 
const enableDarkMode = () => {
  document.body.classList.add('darkmode');
  // 2. Update darkMode in localStorage
  localStorage.setItem('theme', 'dark');
}
// cambio de light mode a dark mode.
const disableDarkMode = () => {
  // 1. Remove the class from the body
  document.body.classList.remove('darkmode');
  // 2. Update darkMode in localStorage 
  localStorage.setItem('theme', 'light');
}

Enter fullscreen mode Exit fullscreen mode

Evento botón

// btn btn-theme
const btnTheme = document.querySelector('#btn-theme');

btnTheme.addEventListener('click', () => {
  // 1. Check if dark mode is enabled
  localStorage.getItem('theme') === 'dark' ? disableDarkMode() : enableDarkMode();

})
Enter fullscreen mode Exit fullscreen mode

Nota hay una mejor solución para no duplicar tanto las variables de css y las clases. Que es controlando desde JS. Lo vemos en el proximo branch.

Con Javascript pero sin media query

  • Se elimina la clase .lightmode y se saca el @media (prefers-color-scheme: dark) se realiza todo con Javascript y se almacena en el LocalStorage.

  • De css solo nos queda las variables en el root y en la clase .darkmode, la clase .darkmode se asigna al body y se remueve cuando está en modo light quedando aplicadas las variables del root base.

/* variables globales */
:root {
  --header-color: #f5f5f5;
  --header-back-color: rgb(84, 121, 241);
  --main-back-color: #f5f5f5;
  --main-color: #333;
  --header-container-max-width: 70rem;
}

.darkmode {
  --header-color: #b2b2b2;
  --header-back-color: rgb(31, 31, 31);
  --main-back-color: #595959;
  --main-color: rgb(235, 235, 235);
  --header-container-max-width: 70rem;
}
Enter fullscreen mode Exit fullscreen mode
  • Cuando carga la página verificamos que thema esta en el sistema y que theme en el local host. Deja el que se encuentre en el Localhost.
// Detectar el color del sistema
const detectColorScheme = () => {
  const localTheme = localStorage.getItem('theme');
  // Verificar que theme tiene el sistema/navegador 
  if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
    // dark mode
    (localTheme === 'dark' || localTheme === null) ? enableDarkMode() : disableDarkMode();
  } else {
    (localTheme === 'dark') ? enableDarkMode() : disableDarkMode();
  }
}

// Verifica si hay cambios en el thema y lo cambia
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
  event.matches ? enableDarkMode() : disableDarkMode();
});

// Detectar el color del sistema
detectColorScheme();

Enter fullscreen mode Exit fullscreen mode
  • Aquí por último las funciones auxiliares y el control del botón para cambiar de theme, entre dark y light.
// btn btn-theme
const btnTheme = document.querySelector('#btn-theme');

btnTheme.addEventListener('click', () => {
  // 1. Check if dark mode is enabled
  localStorage.getItem('theme') === 'dark' ? disableDarkMode() : enableDarkMode();

})

// cambio de dark mode a light mode. 
const enableDarkMode = () => {
  document.body.classList.add('darkmode');
  // 2. Update darkMode in localStorage
  localStorage.setItem('theme', 'dark');
}
// cambio de light mode a dark mode.
const disableDarkMode = () => {
  // 1. Remove the class from the body
  document.body.classList.remove('darkmode');
  // 2. Update darkMode in localStorage 
  localStorage.setItem('theme', 'light');
}

Enter fullscreen mode Exit fullscreen mode

Nota final: Uds podrían agregar mas temas de colores o dejar que el cliente selecciones los colores y los guarde en el localstorage o en la base de datos.


Cada punto esta un branch distinto.

Heroku

Simplify your DevOps and maximize your time.

Since 2007, Heroku has been the go-to platform for developers as it monitors uptime, performance, and infrastructure concerns, allowing you to focus on writing code.

Learn More

Top comments (0)

nextjs tutorial video

Youtube Tutorial Series 📺

So you built a Next.js app, but you need a clear view of the entire operation flow to be able to identify performance bottlenecks before you launch. But how do you get started? Get the essentials on tracing for Next.js from @nikolovlazar in this video series 👀

Watch the Youtube series

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay