prefers-color-scheme: Hola, oscuridad, mi viejo amigo

¿Sobrecargado o necesidad? Aprende todo sobre el modo oscuro y cómo lograrlo en beneficio de los usuarios.

Modo oscuro antes del Modo oscuro

Monitor de computadora con pantalla verde
Pantalla verde (Fuente)

Cerramos el círculo con el modo oscuro. En los albores de la computación personal, el modo oscuro no era una cuestión de elección, sino un hecho: los monitores de computadora CRT monocromos funcionaban disparando haces de electrones en una pantalla fosforescente, y el fósforo que se usaba en los primeros CRT era verde. Debido a que el texto se mostraba en verde y el resto de la pantalla era negro, estos modelos a menudo se denominaban pantallas verdes.

Procesamiento de texto en negro sobre blanco
Oscuro sobre blanco (Source)

Las CRT en color que se introdujeron posteriormente mostraban varios colores con el uso de fósforos rojos, verdes y azules. Para crear el color blanco, activaron los tres fosfuros de forma simultánea. Con la llegada de una publicación para computadoras WYSIWYG más sofisticada, la idea de hacer que el documento virtual se asemeje a una hoja de papel física se volvió popular.

Página web en blanco y oscuro en el navegador WorldWideWeb
El navegador WorldWideWeb (fuente)

Aquí es donde comenzó el negro sobre blanco como tendencia de diseño, que se trasladó a la primera web basada en documentos. El primer navegador, WorldWideWeb (recuerda que todavía no se inventó el CSS), presentaba las páginas web de esta manera. Dato curioso: el segundo navegador de la historia, el Line Mode Browser (un navegador basado en la terminal), era verde sobre negro. En la actualidad, las páginas web y las apps web suelen diseñarse con texto oscuro sobre un fondo claro, una suposición de referencia que también está codificada en los archivos de diseño de usuario-agente, incluido el de Chrome.

Smartphone usado mientras está acostado en la cama
Smartphone usado en la cama (fuente: Unsplash)

Los días de los CRT quedaron atrás. El consumo y la creación de contenido se trasladaron a dispositivos móviles que usan pantallas LCD con retroiluminación o AMOLED de bajo consumo. Las computadoras, las tablets y los smartphones más pequeños y fáciles de transportar dieron lugar a nuevos patrones de uso. Las tareas de ocio, como la navegación web, la programación por diversión y los videojuegos de alta gama, a menudo se realizan después del horario laboral en entornos poco iluminados. Las personas incluso disfrutan de sus dispositivos en la cama durante la noche. Cuanto más personas usan sus dispositivos en la oscuridad, más popular se vuelve la idea de volver a los orígenes del modo oscuro.

Por qué usar el modo oscuro

Modo oscuro por motivos estéticos

Cuando se les pregunta por qué les gusta o quieren el modo oscuro, la respuesta más popular es que "es más fácil para la vista", seguida de "es elegante y hermoso". En su documentación para desarrolladores sobre el modo oscuro, Apple escribe de forma explícita lo siguiente: “La elección de habilitar una apariencia oscura o clara es una estética para la mayoría de los usuarios, y es posible que no se relacione con las condiciones lumínicas del ambiente”.

CloseView en el sistema Mac OS 7 con
CloseView de System 7 (fuente)

El modo oscuro como herramienta de accesibilidad

También hay personas que necesitan el modo oscuro y lo usan como otra herramienta de accesibilidad, por ejemplo, los usuarios con visión reducida. La primera aparición de una herramienta de accesibilidad de este tipo que pude encontrar es la función CloseView de System 7, que tenía un botón de activación para negro sobre blanco y blanco sobre negro. Si bien el sistema 7 admitía colores, la interfaz de usuario predeterminada aún era en blanco y negro.

Estas implementaciones basadas en inversión demostraron sus debilidades una vez que se introdujo el color. Una investigación sobre usuarios realizada por Szpiro et al. sobre cómo las personas con acceso de visión reducida a dispositivos informáticos mostró que a todos los usuarios entrevistados no les gustaban las imágenes invertidas, pero que muchos prefieren el texto claro sobre un fondo oscuro. Apple se adapta a esta preferencia del usuario con una función llamada Smart Invert, que invierte los colores de la pantalla, excepto las imágenes, el contenido multimedia y algunas apps que usan estilos de colores oscuros.

Una forma especial de visión baja es el síndrome de visión por computadora, también conocido como fatiga visual digital, que se define como “la combinación de problemas oculares y visuales asociados con el uso de computadoras (incluidas computadoras de escritorio, laptops y tablets) y otras pantallas electrónicas (p. ej., smartphones y dispositivos de lectura electrónicos)”. Se propuso que el uso de dispositivos electrónicos por parte de los adolescentes, en especial por la noche, aumenta el riesgo de una duración más corta del sueño, una latencia de inicio del sueño más larga y una mayor deficiencia del sueño. Además, se informó ampliamente que la exposición a la luz azul está involucrada en la regulación del ritmo circadiano y el ciclo del sueño, y que los entornos de luz irregulares pueden provocar privación del sueño, lo que podría afectar el estado de ánimo y el rendimiento de las tareas, según una investigación de Rosenfield. Para limitar estos efectos negativos, reducir la luz azul ajustando la temperatura de color de la pantalla con funciones como Night Shift de iOS o la Luz nocturna de Android puede ayudar, además de evitar las luces brillantes o irregulares en general a través de temas oscuros o modos oscuros.

Ahorro de energía del modo oscuro en pantallas AMOLED

Por último, se sabe que el modo oscuro ahorra mucha energía en las pantallas AMOLED. Los casos de éxito de Android que se enfocaron en apps populares de Google, como YouTube, demostraron que el ahorro de energía puede ser de hasta un 60%. En el siguiente video, encontrarás más detalles sobre estos casos de éxito y el ahorro de energía por app.

Activar el modo oscuro en el sistema operativo

Ahora que explicamos por qué el modo oscuro es tan importante para muchos usuarios, veamos cómo puedes admitirlo.

Configuración del modo oscuro en Android Q
Configuración del tema oscuro de Android Q

Los sistemas operativos que admiten un modo oscuro o un tema oscuro suelen tener una opción para activarlo en algún lugar de la configuración. En macOS X, se encuentra en la sección General de las preferencias del sistema y se llama Diseño (captura de pantalla). En Windows 10, se encuentra en la sección Colores y se llama Elige tu color (captura de pantalla). En Android Q, puedes encontrarlo en Pantalla como un interruptor de activación Tema oscuro (captura de pantalla). En iOS 13, puedes cambiar la Diseño en la sección Pantalla y brillo de la configuración (captura de pantalla).

La búsqueda de medios prefers-color-scheme

Una última teoría antes de continuar. Las consultas de medios permiten a los autores probar y consultar valores o funciones del usuario-agente o dispositivo de visualización, independientemente del documento que se renderiza. Se usan en la regla @media de CSS para aplicar diseños de forma condicional a un documento y en otros lenguajes y contextos, como HTML y JavaScript. El nivel 5 de las consultas de medios introduce las llamadas funciones de medios de preferencia del usuario, es decir, una forma para que los sitios detecten la forma preferida del usuario de mostrar contenido.

La función multimedia prefers-color-scheme se usa para detectar si el usuario solicitó que la página use un tema de color oscuro o claro. Funciona con los siguientes valores:

  • light: Indica que el usuario notificó al sistema que prefiere una página con un tema claro (texto oscuro sobre fondo claro).
  • dark: Indica que el usuario notificó al sistema que prefiere una página con un tema oscuro (texto claro sobre fondo oscuro).

Compatibilidad con el modo oscuro

Cómo saber si el navegador admite el modo oscuro

Como el modo oscuro se informa a través de una consulta de contenido multimedia, puedes verificar fácilmente si el navegador actual admite el modo oscuro comprobando si la consulta de contenido multimedia prefers-color-scheme coincide. Observa que no incluyo ningún valor, sino que solo reviso si la consulta de medios coincide.

if (window.matchMedia('(prefers-color-scheme)').media !== 'not all') {
  console.log('🎉 Dark mode is supported');
}

En el momento de escribir este artículo, prefers-color-scheme es compatible con Chrome y Edge a partir de la versión 76, Firefox a partir de la versión 67 y Safari a partir de la versión 12.1 en macOS y de la versión 13 en iOS, tanto en computadoras como en dispositivos móviles (si está disponible). Para todos los demás navegadores, consulta ¿Puedo usar las tablas de asistencia?.

Cómo obtener información sobre las preferencias de un usuario en el momento de la solicitud

El encabezado de sugerencia de cliente Sec-CH-Prefers-Color-Scheme permite que los sitios obtengan las preferencias de esquema de colores del usuario de forma opcional en el momento de la solicitud, lo que permite que los servidores inserten el CSS correcto y, por lo tanto, evitar un destello de tema de color incorrecto.

Modo oscuro en la práctica

Por último, veamos cómo se ve en la práctica la compatibilidad con el modo oscuro. Al igual que con Highlander, con el modo oscuro solo puede haber uno: oscuro o claro, pero nunca ambos. ¿Por qué menciono esto? Porque este hecho debería tener un impacto en la estrategia de carga. No fuerces a los usuarios a descargar CSS en la ruta de acceso de renderización crítica para un modo que no usan actualmente. Para optimizar la velocidad de carga, dividí mi CSS de la app de ejemplo, que muestra las siguientes recomendaciones en la práctica, en tres partes para aplazar el CSS no esencial:

  • style.css que contiene reglas genéricas que se usan de forma universal en el sitio.
  • dark.css que solo contiene las reglas necesarias para el modo oscuro.
  • light.css que contiene solo las reglas necesarias para el modo claro.

Estrategia de carga

Los dos últimos, light.css y dark.css, se cargan de forma condicional con una consulta <link media>. Inicialmente, no todos los navegadores admitirán prefers-color-scheme (detectable con el patrón anterior), que trato de forma dinámica cargando el archivo light.css predeterminado a través de un elemento <link rel="stylesheet"> insertado de forma condicional en una pequeña secuencia de comandos intercalada (la luz es una opción arbitraria, también podría haber hecho oscura la experiencia de resguardo predeterminada). Para evitar un destello de contenido sin estilo, oculto el contenido de la página hasta que se cargue light.css.

<script>
  // If `prefers-color-scheme` is not supported, fall back to light mode.
  // In this case, light.css will be downloaded with `highest` priority.
  if (window.matchMedia('(prefers-color-scheme: dark)').media === 'not all') {
    document.documentElement.style.display = 'none';
    document.head.insertAdjacentHTML(
      'beforeend',
      '<link rel="stylesheet" href="/light.css" onload="document.documentElement.style.display = \'\'">',
    );
  }
</script>
<!--
  Conditionally either load the light or the dark stylesheet. The matching file
  will be downloaded with `highest`, the non-matching file with `lowest`
  priority. If the browser doesn't support `prefers-color-scheme`, the media
  query is unknown and the files are downloaded with `lowest` priority (but
  above I already force `highest` priority for my default light experience).
-->
<link rel="stylesheet" href="/dark.css" media="(prefers-color-scheme: dark)" />
<link
  rel="stylesheet"
  href="/light.css"
  media="(prefers-color-scheme: light)"
/>
<!-- The main stylesheet -->
<link rel="stylesheet" href="/style.css" />

Arquitectura de la hoja de estilo

Aprovecho al máximo las variables de CSS, lo que permite que mi style.css genérico sea, bueno, genérico, y toda la personalización del modo claro o oscuro se realice en los otros dos archivos dark.css y light.css. A continuación, puedes ver un extracto de los estilos reales, pero debería ser suficiente para transmitir la idea general. Declaro dos variables, -⁠-⁠color y -⁠-⁠background-color, que, en esencia, crean un tema de referencia oscuro sobre claro y claro sobre oscuro.

/* light.css: 👉 dark-on-light */
:root {
  --color: rgb(5, 5, 5);
  --background-color: rgb(250, 250, 250);
}
/* dark.css: 👉 light-on-dark */
:root {
  --color: rgb(250, 250, 250);
  --background-color: rgb(5, 5, 5);
}

En mi style.css, uso estas variables en la regla body { … }. Como se definen en la seudoclase CSS :root, un selector que en HTML representa el elemento <html> y es idéntico al selector html, excepto que su especificidad es mayor, se aplican en cascada, lo que me sirve para declarar variables globales de CSS.

/* style.css */
:root {
  color-scheme: light dark;
}

body {
  color: var(--color);
  background-color: var(--background-color);
}

En la muestra de código anterior, es probable que hayas notado una propiedad color-scheme con el valor light dark separado por espacios.

Esto le indica al navegador qué temas de color admite mi app y le permite activar variantes especiales de la hoja de estilo del usuario-agente, lo que es útil, por ejemplo, para permitir que el navegador renderice campos del formulario con un fondo oscuro y texto claro, ajuste las barras de desplazamiento o habilite un color de resaltado adaptado al tema. Los detalles exactos de color-scheme se especifican en el nivel 1 del módulo de ajuste de color de CSS.

Todo lo demás es solo cuestión de definir variables CSS para los elementos que son importantes en mi sitio. Organizar los estilos semánticamente ayuda mucho cuando se trabaja con el modo oscuro. Por ejemplo, en lugar de -⁠-⁠highlight-yellow, considera llamar a la variable -⁠-⁠accent-color, ya que es posible que “amarillo” no sea amarillo en el modo oscuro o viceversa. A continuación, se muestra un ejemplo de algunas variables más que uso en mi ejemplo.

/* dark.css */
:root {
  --color: rgb(250, 250, 250);
  --background-color: rgb(5, 5, 5);
  --link-color: rgb(0, 188, 212);
  --main-headline-color: rgb(233, 30, 99);
  --accent-background-color: rgb(0, 188, 212);
  --accent-color: rgb(5, 5, 5);
}
/* light.css */
:root {
  --color: rgb(5, 5, 5);
  --background-color: rgb(250, 250, 250);
  --link-color: rgb(0, 0, 238);
  --main-headline-color: rgb(0, 0, 192);
  --accent-background-color: rgb(0, 0, 238);
  --accent-color: rgb(250, 250, 250);
}

Ejemplo completo

En la siguiente incorporación de Glitch, puedes ver el ejemplo completo que pone en práctica los conceptos anteriores. Intenta activar o desactivar el modo oscuro en la configuración de tu sistema operativo y observa cómo reacciona la página.

Impacto de la carga

Cuando juegues con este ejemplo, podrás ver por qué cargo mi dark.css y light.css a través de consultas de contenido multimedia. Intenta activar el modo oscuro y volver a cargar la página: los estilos de hoja de estilo que no coinciden en este momento se siguen cargando, pero con la prioridad más baja, de modo que nunca compitan con los recursos que necesita el sitio en este momento.

Diagrama de carga de red que muestra cómo, en el modo claro, el CSS del modo oscuro se carga con la prioridad más baja
El sitio en modo claro carga el CSS del modo oscuro con la prioridad más baja.
Diagrama de carga de red que muestra cómo, en el modo oscuro, el CSS del modo claro se carga con la prioridad más baja
El sitio en modo oscuro carga el CSS del modo claro con la prioridad más baja.
Diagrama de carga de red que muestra cómo, en el modo claro predeterminado, el CSS del modo oscuro se carga con la prioridad más baja
El sitio en modo claro predeterminado en un navegador que no es compatible con prefers-color-scheme carga el CSS del modo oscuro con la prioridad más baja.

Cómo reaccionar a los cambios del modo oscuro

Al igual que cualquier otro cambio de consulta de medios, los cambios en el modo oscuro se pueden suscribir a través de JavaScript. Puedes usar esto para, por ejemplo, cambiar de forma dinámica el favicon de una página o cambiar el <meta name="theme-color"> que determina el color de la barra de URL en Chrome. En el ejemplo completo anterior, se muestra esto en acción. Para ver los cambios en el color del tema y el ícono de página, abre la demostración en una pestaña separada.

const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
darkModeMediaQuery.addEventListener('change', (e) => {
  const darkModeOn = e.matches;
  console.log(`Dark mode is ${darkModeOn ? '🌒 on' : '☀️ off'}.`);
});

A partir de Chromium 93 y Safari 15, puedes ajustar el color en función de una consulta de medios con el atributo media del elemento de color del tema meta. Se elegirá la primera que coincida. Por ejemplo, puedes tener un color para el modo claro y otro para el modo oscuro. En el momento de la redacción, no puedes definirlos en tu manifiesto. Consulta el problema de GitHub w3c/manifest#975.

<meta
  name="theme-color"
  media="(prefers-color-scheme: light)"
  content="white"
/>
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="black" />

Depura y prueba el modo oscuro

Emulación de prefers-color-scheme en DevTools

Cambiar el esquema de colores de todo el sistema operativo puede ser muy molesto, por lo que DevTools de Chrome ahora te permite emular el esquema de colores preferido del usuario de una manera que solo afecte a la pestaña visible actualmente. Abre el menú de comandos, comienza a escribir Rendering, ejecuta el comando Show Rendering y, luego, cambia la opción Emulate CSS media feature prefers-color-scheme.

Captura de pantalla de la opción “Emular prefers-color-scheme de la función de medios de CSS” que se encuentra en la pestaña Renderización de Chrome DevTools

Cómo tomar una captura de pantalla de prefers-color-scheme con Puppeteer

Puppeteer es una biblioteca de Node.js que proporciona una API de alto nivel para controlar Chrome o Chromium a través del protocolo de DevTools. Con dark-mode-screenshot, proporcionamos una secuencia de comandos de Puppeteer que te permite crear capturas de pantalla de tus páginas en modo oscuro y claro. Puedes ejecutar esta secuencia de comandos como una acción única o, como alternativa, hacer que forme parte de tu suite de pruebas de integración continua (CI).

npx dark-mode-screenshot --url https://googlechromelabs.github.io/dark-mode-toggle/demo/ --output screenshot --fullPage --pause 750

Prácticas recomendadas para el modo oscuro

Evita el blanco puro

Un pequeño detalle que quizás hayas notado es que no uso blanco puro. En cambio, para evitar que brille y sangra en el contenido oscuro que lo rodea, elijo un blanco un poco más oscuro. Algo como rgb(250, 250, 250) funciona bien.

Cómo volver a colorear y oscurecer imágenes fotográficas

Si comparas las dos capturas de pantalla que aparecen a continuación, notarás que no solo cambió el tema principal de oscuro sobre claro a claro sobre oscuro, sino que también la imagen hero se ve un poco diferente. Mi investigación sobre usuarios mostró que la mayoría de las personas encuestadas prefieren imágenes un poco menos brillantes y vibrantes cuando el modo oscuro está activo. Me refiero a esto como recolorización.

La imagen hero se oscureció un poco en el modo oscuro.
La imagen hero se oscurece un poco en el modo oscuro.
Imagen hero normal en modo claro.
Imagen hero estándar en modo claro.

La recolorización se puede lograr a través de un filtro CSS en mis imágenes. Utilizo un selector CSS que coincide con todas las imágenes que no tienen .svg en su URL. La idea es que puedo darles a los gráficos vectoriales (íconos) un tratamiento de recoloración diferente al de mis imágenes (fotos). Obtén más información sobre esto en el próximo párrafo. Observa cómo vuelvo a usar una variable CSS para poder cambiar mi filtro de forma flexible más adelante.

Como la recolorización solo es necesaria en el modo oscuro, es decir, cuando dark.css está activo, no hay reglas correspondientes en light.css.

/* dark.css */
--image-filter: grayscale(50%);

img:not([src*='.svg']) {
  filter: var(--image-filter);
}

Cómo personalizar la intensidad de la recoloración del modo oscuro con JavaScript

No todos somos iguales y las personas tienen diferentes necesidades de modo oscuro. Si me adhiero al método de recoloración descrito anteriormente, puedo hacer que la intensidad de escala de grises sea una preferencia del usuario que puedo cambiar a través de JavaScript. Si configuro un valor de 0%, también puedo inhabilitar la recoloración por completo. Ten en cuenta que document.documentElement proporciona una referencia al elemento raíz del documento, es decir, al mismo elemento al que puedo hacer referencia con la pseudoclase :root de CSS.

const filter = 'grayscale(70%)';
document.documentElement.style.setProperty('--image-filter', value);

Invierte gráficos vectoriales y íconos

En el caso de los gráficos vectoriales, que en mi caso se usan como íconos a los que hago referencia a través de elementos <img>, uso un método de recoloración diferente. Si bien las investigaciones mostraron que a las personas no les gusta la inversión para las fotos, funciona muy bien para la mayoría de los íconos. Una vez más, uso variables CSS para determinar el importe de inversión en el estado normal y en el estado :hover.

Los íconos se invierten en el modo oscuro.
Los íconos se invierten en el modo oscuro.
Íconos normales en modo claro.
Íconos normales en modo claro.

Ten en cuenta que, una vez más, solo invertí los íconos en dark.css, pero no en light.css, y cómo :hover obtiene una intensidad de inversión diferente en los dos casos para que el ícono se vea un poco más oscuro o un poco más claro, según el modo que haya seleccionado el usuario.

/* dark.css */
--icon-filter: invert(100%);
--icon-filter_hover: invert(40%);

img[src*='.svg'] {
  filter: var(--icon-filter);
}
/* light.css */
--icon-filter_hover: invert(60%);
/* style.css */
img[src*='.svg']:hover {
  filter: var(--icon-filter_hover);
}

Usa currentColor para los SVG intercalados.

Para imágenes SVG intercaladas, en lugar de usar filtros de inversión, puedes aprovechar la palabra clave de CSS currentColor que representa el valor de la propiedad color de un elemento. Esto te permite usar el valor color en propiedades que no lo reciben de forma predeterminada. De manera conveniente, si se usa currentColor como valor de los atributos fill o stroke de SVG, toma su valor del valor heredado de la propiedad de color. Mejor aún: esto también funciona para <svg><use href="…"></svg>, por lo que puedes tener recursos separados y currentColor se seguirá aplicando en el contexto. Ten en cuenta que esto solo funciona para SVG incorporados o <use href="…">, pero no para los SVG a los que se hace referencia como src de una imagen o de alguna manera a través de CSS. Puedes ver esto aplicado en la siguiente demostración.

<!-- Some inline SVG -->
<svg xmlns="http://www.w3.org/2000/svg"
    stroke="currentColor"
>
  […]
</svg>

Transiciones fluidas entre modos

Cambiar del modo oscuro al modo claro, o viceversa, se puede suavizar gracias al hecho de que tanto color como background-color son propiedades de CSS animadas. Crear la animación es tan fácil como declarar dos transition para las dos propiedades. En el siguiente ejemplo, se ilustra la idea general. Puedes experimentarla en vivo en la demo.

body {
  --duration: 0.5s;
  --timing: ease;

  color: var(--color);
  background-color: var(--background-color);

  transition: color var(--duration) var(--timing), background-color var(
        --duration
      ) var(--timing);
}

Dirección de arte con modo oscuro

Si bien, por motivos de rendimiento de carga en general, recomiendo trabajar exclusivamente con prefers-color-scheme en el atributo media de los elementos <link> (en lugar de intercalarlo en los diseños de página), hay situaciones en las que es posible que desees trabajar con prefers-color-scheme directamente intercalado en tu código HTML. La dirección artística es una de esas situaciones. En la Web, la dirección de arte se ocupa de la apariencia visual general de una página y de cómo se comunica visualmente, estimula los estados de ánimo, contrasta las características y atrae psicológicamente a un público objetivo.

Con el modo oscuro, depende del criterio del diseñador decidir cuál es la mejor imagen en un modo en particular y si la recolorización de las imágenes no es lo suficientemente buena. Si se usa con el elemento <picture>, el <source> de la imagen que se mostrará puede depender del atributo media. En el siguiente ejemplo, muestro el hemisferio occidental para el modo oscuro y el hemisferio oriental para el modo claro, o cuando no se especifica una preferencia, se usa el hemisferio oriental de forma predeterminada en todos los demás casos. Por supuesto, esto es solo a modo de ejemplo. Activa o desactiva el modo oscuro en tu dispositivo para ver la diferencia.

<picture>
  <source srcset="western.webp" media="(prefers-color-scheme: dark)" />
  <source srcset="eastern.webp" media="(prefers-color-scheme: light)" />
  <img src="eastern.webp" />
</picture>

Modo oscuro, pero agrega una opción para inhabilitarlo

Como se mencionó en la sección por qué el modo oscuro anterior, el modo oscuro es una opción estética para la mayoría de los usuarios. En consecuencia, es posible que a algunos usuarios les guste tener la IU del sistema operativo en modo oscuro, pero que prefieran ver sus páginas web de la forma en que están acostumbrados a verlas. Un buen patrón es adherirse inicialmente al indicador que envía el navegador a través de prefers-color-scheme, pero permitir que los usuarios anulen su configuración a nivel del sistema de forma opcional.

El elemento personalizado <dark-mode-toggle>

Por supuesto, puedes crear el código para esto, pero también puedes usar un elemento personalizado (componente web) listo para usar que creé para este propósito. Se llama <dark-mode-toggle> y agrega un botón de activación (modo oscuro: activado/desactivado) o un selector de temas (tema: claro/oscuro) a tu página que puedes personalizar por completo. En la siguiente demostración, se muestra el elemento en acción (también lo 🤫 incluí en silencio en todos los otros ejemplos anteriores).

<dark-mode-toggle
  legend="Theme Switcher"
  appearance="switch"
  dark="Dark"
  light="Light"
  remember="Remember this"
></dark-mode-toggle>
dark-mode-toggle en modo claro.
<dark-mode-toggle> en modo claro.
dark-mode-toggle en modo claro.
<dark-mode-toggle> en modo oscuro.

En la siguiente demostración, haz clic o presiona los controles del modo oscuro en la esquina superior derecha. Si marcas la casilla de verificación en el tercer y cuarto control, verás cómo se recuerda la selección de modo incluso cuando vuelves a cargar la página. Esto permite que los visitantes mantengan su sistema operativo en modo oscuro, pero disfruten de tu sitio en modo claro o viceversa.

Conclusiones

Trabajar con el modo oscuro y admitirlo es divertido y abre nuevas vías de diseño. Para algunos de tus visitantes, puede ser la diferencia entre no poder usar tu sitio y ser un usuario satisfecho. Existen algunos errores y se requieren pruebas cuidadosas, pero el modo oscuro es una gran oportunidad para demostrar que te importan todos tus usuarios. Las prácticas recomendadas que se mencionan en esta publicación y las ayudas, como el elemento personalizado <dark-mode-toggle>, deberían darte confianza en tu capacidad para crear una experiencia increíble del modo oscuro. Cuéntanos en Twitter qué creaste y si esta publicación te resultó útil o si tienes sugerencias para mejorarla. ¡Gracias por leer esta información! 🌒

Recursos para la consulta de contenido multimedia prefers-color-scheme:

Recursos para la metaetiqueta color-scheme y la propiedad CSS:

Vínculos generales del modo oscuro:

Artículos de investigación de antecedentes para esta publicación:

Agradecimientos

La función multimedia prefers-color-scheme, la propiedad color-scheme de CSS y la metaetiqueta relacionada son el trabajo de implementación de 👏 Rune Lillesveen. Rune también es coeditor de la especificación CSS Color Adjustment Module Level 1. Me gustaría 🙏 agradecer a Lukasz Zbylut, Rowan Merewood, Chirag Desai y Rob Dodson por sus revisiones exhaustivas de este artículo. La estrategia de carga es una idea de Jake Archibald. Emilio Cobos Álvarez me indicó el método de detección de prefers-color-scheme correcto. El consejo con SVGs y currentColor de referencia provino de Timothy Hatcher. Por último, agradezco a los muchos participantes anónimos de los diversos estudios de usuarios que ayudaron a definir las recomendaciones de este artículo. Imagen hero de Nathan Anderson.