Cómo agregué el modo oscuro a mi sitio web

Las instrucciones paso a paso para hacer 2 versiones de su sitio web, para que sea perfecto tanto para uso diurno como nocturno.

Dark mode

Actualización: ahora uso Media Queries Level 5:prefers-color-scheme

losMedia Queries Level 5especificacióncontiene un nuevoprefers-color-schemefunción multimedia.

Actualmente, esto es compatible con todos los navegadores principales. Chrome / Edge desde la versión 76, Firefox desde 67 y Safari (desde la versión 12.1). Incluso iOS Safari,

Podemos usarlo para saber si el usuario está navegando por la página en modo oscuro o claro:

@media (prefers-color-scheme: dark) {
  body {
    background-color: black;
    color: white;
  }
}
@media (prefers-color-scheme: light) {
  body {
    background-color: white;
    color: black;
  }
}

Ahora lo uso para mostrar una versión clara del sitio de forma predeterminada y una versión oscura si el sistema está en modo oscuro.

Si el sistema no tiene el modo oscuro incorporado (Windows / macOS antiguo, Linux), entonces mi sugerencia es usar una extensión comoOjo de la nocheo similar.

Cómo implementé el modo oscuro antesprefers-color-schemeestaba disponible

Recientemente rediseñé mi sitio web. Aquí hay 2 imágenes de cómo se veía, como referencia:

Old homepage

Old post page

Diseñé este sitio web hace casi 1 año e hice muchos cambios a lo largo del camino, al igual que hacemos con cualquier sitio web.

Con el tiempo, envejecí con el diseño: el título es demasiado grande, se pierde demasiado espacio en lugar de mostrar el contenido directamente, y así sucesivamente.

Me senté ayer por la noche y comencé a volver a imaginar el sitio web, y terminé el rediseño esta mañana:

New homepage

New post page

¡Mucho mejor! El contenido, lo más importante, es más destacado.

Usé una fuente monoespaciada (Inconsolata) porque como blog de programación es agradable, a pesar de la legibilidad reducida y el tamaño de página aumentado debido al uso de fuentes, porque yoquereresa fuente en mi sitio. Me gusta más, y dado que mi sitio es una gran parte de mi actividad diaria, quería que fuera como quiero.

Solo me perdí una cosa:modo oscuro. Como estaba en el proceso de rediseño, tenía en mente la opción del modo oscuro.

Como lo hice Primero, agregué Moon Emoji 🌓 en la barra lateral, como una forma de permitir que las personas cambien el modo de claro a oscuro.

Luego, agregué un fragmento de JavaScript que se ejecuta cuando se hace clic en él. Lo acabo de agregar alonclickcontrolador de eventos en línea en el HTML, sin volverse más sofisticado:

<p>
  <a href="#" onclick="localStorage.setItem('mode', (localStorage.getItem('mode') || 'dark') === 'dark' ? 'light' : 'dark'); localStorage.getItem('mode') === 'dark' ? document.querySelector('body').classList.add('dark') : document.querySelector('body').classList.remove('dark')" title="Dark/light
</p>

Este es el JavaScript que se ejecuta en el clic:

localStorage.setItem('mode', (localStorage.getItem('mode') || 'dark') === 'dark' ? 'light' : 'dark'); localStorage.getItem('mode') === 'dark' ? document.querySelector('body').classList.add('dark') : document.querySelector('body').classList.remove('dark')

Es un poco complicado, pero básicamente compruebo si elmodepropiedad en elalmacenamiento locales 'oscuro' (y por defecto es oscuro si aún no está configurado, usando el||operador), y configuré lo contrario de eso en el almacenamiento local.

Entonces asigno eldarkclase a labodyElemento HTML, por lo que podemos usar CSS para diseñar la página en modo oscuro.

Otro script se ejecuta tan pronto como se carga el DOM y comprueba si el modo está oscuro. Si es así, agrega eldarkclase a labodyElemento HTML:

document.addEventListener('DOMContentLoaded', (event) => {
  ((localStorage.getItem('mode') || 'dark') === 'dark') ? document.querySelector('body').classList.add('dark') : document.querySelector('body').classList.remove('dark')
})

Ahora, si las personas cambian de modo, su elección se recordará la próxima vez que carguen la página.

Luego agregué muchas instrucciones CSS al CSS, todas con el prefijobody.dark. Como estos:

body.dark {
  background-color: rgb(30,34,39);
  color: #fff;
}
body.dark code[class*=language-],
body.dark table tbody>tr:nth-child(odd)>td,
body.dark table tbody>tr:nth-child(odd)>th {
  background: #282c34
}

¡Ahora las cosas ya deberían estar funcionando! Aquí está mi sitio en modo oscuro:

Dark homepage

Dark post page

Agregué eldarkclase a labodyelemento de forma predeterminada, para hacer que el modo oscuro sea el predeterminado:

<body class="dark">
  ...
</body>

¿Por qué? Primero, me gustó más. Luego, hice una encuesta en Twitter y a la gente le gustó más.

Poll

Pero también por una razón técnica, muy simple en realidad. No almaceno la elección del usuario en el lado del servidor, por lo que no tengo forma de saber el modo hasta que el almacenamiento local esté disponible.

Podría hacer eso si el sitio se generó en el lado del servidor, pero es un sitio estático, por lo que siempre sirvo la misma página a todos los que la solicitan. Incluso si tengo una cookie, no tengo lugar para procesarla (por otro lado, esto significa que mis páginas se cargan más rápido).

Entonces, cuando alguien navega a otra página de mi sitio, o carga la página por primera vez en una segunda visita, no quiero mostrar una página brillante mientras determino el modo. Quizás el visitante esté codificando en medio de la noche en una habitación oscura.

Prefiero hacerlo en modo claro: mostrar una página oscura durante un par de milisegundos y luego volverla a poner en blanco.


Más tutoriales de laboratorio: