DEV Community

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

Posted on

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.

Discussion (0)