10 puntos por GN⁺ 2026-04-20 | 1 comentarios | Compartir por WhatsApp
  • Resumen de una clasificación en 8 niveles que amplía gradualmente el alcance de implementación del modo oscuro, desde funciones básicas del navegador hasta media queries de JavaScript
  • La forma más simple es configurar que siga la preferencia de esquema de color del usuario solo con declarar <meta name="color-scheme" content="light dark"> o color-scheme: light dark
  • En niveles más altos, la función light-dark(), @media (prefers-color-scheme: dark) y hojas de estilo separadas por esquema permiten ajustar ampliamente no solo los colores, sino también imágenes y sombras
  • También es posible crear un selector que no siga solo la configuración del sistema del usuario y ofrezca tres opciones: Automatic, light y dark; además, se puede detectar el tema con :has() y el elemento meta real
  • Incluye las limitaciones de accesibilidad de Safari y observaciones sobre cómo funciona prefers-color-scheme al imprimir, mostrando que con funciones recientes de CSS ahora es mucho más fácil integrar modos claro y oscuro

Implementación del modo oscuro por niveles

  • Level 1: Barebone

    • Incluso sin una sola línea de CSS se puede activar la distinción entre light/dark, y basta con agregar <meta name="color-scheme" content="light dark"> en el head del documento para que el navegador empiece a seguir la preferencia de esquema de color del usuario
    • En teoría, el orden de los elementos en el atributo content tiene significado, y los usuarios que no hayan especificado una preferencia de esquema de color reciben el primer valor de la lista separada por espacios
    • Como en la configuración actual de los sistemas operativos no existe una opción para no elegir un esquema de color, en la práctica termina coincidiendo con el esquema configurado en el sistema operativo
    • También se puede indicar un solo valor en content; en ese caso se fuerza ese esquema sin tomar en cuenta la preferencia del usuario
    • Esta meta etiqueta cumple en cierta medida el papel de una forma desde HTML que corresponde al enfoque en CSS de la siguiente etapa
  • Level 2: Basic

    • En CSS, la distinción entre modo claro/oscuro se puede aplicar con la declaración html { color-scheme: light dark; }
    • Si ya existe una meta etiqueta en el DOM, esta declaración no es necesaria; si se puede controlar el HTML, se recomienda usar la meta etiqueta porque el navegador conoce la instrucción antes de parsear el CSS
    • Ambos métodos permiten aprovechar los estilos predeterminados del user agent y el modo claro/oscuro incluido en ellos
    • Si además se agrega CSS pero se limita principalmente al uso de CSS system colors, se puede lograr un diseño bastante ordenado
    • A diferencia de la meta etiqueta, que siempre se aplica a todo el documento, la declaración CSS color-scheme también puede colocarse en lugares distintos del elemento raíz, y esa diferencia abre espacio para usos adicionales
  • Level 3: Benign

    • La función de color light-dark() de CSS, agregada relativamente hace poco, permite ajustes simples para modo claro/oscuro
    • En el ejemplo se usa como background-color: light-dark(black, white); y color: light-dark(white, black);; el primer argumento se aplica en modo claro y el segundo en modo oscuro
    • En los argumentos se pueden poner colores reales directamente o custom properties que se interpreten como color
    • En todo el artículo, este es el único nivel que, al momento de escribirlo, no tiene suficiente soporte de navegadores
  • Level 4: Bold

    • Es posible implementar el cambio a modo oscuro con la media query tradicional @media (prefers-color-scheme: dark)
    • Ya sea que se consulte light o dark, se puede lograr el máximo nivel de personalización, no limitado a simples cambios de color
    • También se pueden hacer ajustes como desaturar imágenes con filtros en modo oscuro o reemplazar box shadows por contornos
  • Level 5: Bisectional

    • Las media queries también se pueden usar en HTML, y al ponerlas en el atributo media del elemento link se pueden separar hojas de estilo por esquema
    • Se muestra como ejemplo conectar light.css y dark.css respectivamente a prefers-color-scheme: light y prefers-color-scheme: dark
    • Si el alcance de personalización es amplio, una estructura con archivos dedicados resulta adecuada, y el navegador puede ignorar el archivo CSS que no coincida con la consulta, por lo que podría reducirse en uno el archivo a descargar
  • Level 6: Ballistic

    • En JavaScript se puede usar la media query de esquema de color con window.matchMedia('(prefers-color-scheme:dark)')
    • Igual que con otras media queries, se puede consultar si corresponde el esquema claro u oscuro y luego ejecutar el procesamiento deseado según ese resultado
    • En una implementación real no hace falta apegarse a una sola técnica de las etapas anteriores; se pueden combinar

Selector del usuario y patrones avanzados

  • Level 7: Beyond

    • No es necesario depender solo de la preferencia del sistema del usuario; se puede construir un color scheme switcher
    • Este selector no es un simple booleano, y necesita un modo Automatic que, como valor predeterminado inicial, siga prefers-color-scheme
    • Al superponer ese selector, el usuario puede elegir uno de tres modos: Automatic, light o dark
  • Level 8: Beguiling

    • Al implementar el selector de Level 7, normalmente se suele agregar una clase .dark o un atributo como data-theme="dark" al elemento HTML
    • En su lugar, se puede usar :has() para consultar directamente si existe <meta name="color-scheme" content="dark">
    • En el ejemplo, bajo el selector html:has(meta[name="color-scheme"][content="dark"]), se configuran variables de CSS como --color-bg y --color-text con valores de modo oscuro
    • Así se puede detectar el tema basándose en el elemento meta real, sin clases ni atributos de datos adicionales

Discusión adicional y observaciones

  • Observación de CSS Naked Day

    • Tras quitar los estilos, en casi todos los sitios visitados se notó la ausencia de modo oscuro, y eso llevó a esta clasificación por niveles del modo oscuro
    • También se menciona que, al crear un sitio nuevo desde cero y escribir estilos nuevos, con las funciones recientes de CSS se ha vuelto muy fácil integrar de fábrica los modos claro y oscuro
  • Problemas de accesibilidad en Safari

    • Se señala que hasta hace relativamente poco Safari no ofrecía colores de enlaces accesibles en modo oscuro
    • Se menciona la experiencia de haber detectado ese problema en un CSS Naked Day anterior y, tras quitar la meta etiqueta, haber usado solo el esquema de color claro
    • Después se volvió a agregar la meta etiqueta, pero reconociendo que para usuarios de versiones antiguas de Safari podría haber una degradación de accesibilidad
    • También se confirmó la ausencia de bordes visibles en los cuadros de texto en el modo oscuro de Safari
    • Como los estilos del user agent por sí solos no garantizan accesibilidad completa incluso usando HTML semántico correcto, se plantea cómo mantener suficiente estilo también en futuros CSS Naked Day
  • Impresión y condición screen and

    • Se menciona que en el ejemplo de Bisectional se usó screen and ... con la intención de excluir impresoras
    • Suponiendo que exista una hoja de estilos base independiente del tema o una hoja de impresión dedicada, se plantea separarlo por seguridad porque el modo oscuro en impresoras podría gastar mucha tinta
    • En las pruebas reales, incluso imprimiendo con el modo oscuro del sistema activado, solo salieron texto negro y papel blanco, y se observó que los navegadores no aplican esos estilos de modo oscuro a la impresión
    • En pruebas adicionales, en la vista previa de impresión prefers-color-scheme siempre se reportó como light, confirmado en Firefox y Chromium
    • Se incluye un comentario en tono de broma sobre que sería una pena si existiera una impresora que usara papel negro y tinta blanca

1 comentarios

 
GN⁺ 2026-04-20
Comentarios de Hacker News
  • Si vas a hacer mucha personalización, tener un archivo dedicado suena razonable, pero creo que la explicación de que el CSS que no coincide con la media query ni siquiera se descarga no refleja cómo se comportan realmente los navegadores. En mi experiencia, el navegador igual lo descarga todo y solo le da distinta prioridad
  • Me preguntaba si todavía no existe una forma de evitar esos destellos tipo flashbang que aparecen mientras se espera el contenido inicial del servidor
    • A mí me parece que definir background-color en userContent.css de Firefox funciona bastante bien
    • Yo simplemente bajé el brillo de la pantalla y desactivé el modo oscuro, y así desapareció el flashbang. De paso, la batería también dura más
  • Yo pensé que este artículo iba a tratar sobre las preferencias respecto al nivel de negro del fondo en modo oscuro. También he oído que el negro puro es mejor para la batería en OLED, y conozco gente que prefiere un gris menos entintado antes que un negro absoluto. Aun así, no estoy seguro de que hagan falta seis niveles; siento que, como mucho, se distinguen 3 o 4 niveles de forma perceptible
    • Yo pensaba que una solución más general sería estandarizar la compatibilidad con Reader Mode. En vez del problema n x m de que cada sitio intente ajustarse a todas las preferencias de todos los usuarios, me parece mejor una estructura donde el sitio solo ofrezca una vista simple del contenido y el navegador se encargue de las preferencias de cada usuario encima de eso
    • Yo prefiero el negro puro en OLED. Siento que mientras menos píxeles estén encendidos, menor es la carga de burn-in y, como de todos modos la vida útil es limitada, a largo plazo preferiría usar el monitor más de 5 años en vez de solo 2 o 3 años
  • Para mí el mejor nivel es 9, o si no 0, que básicamente es apagar la computadora e irse a dormir
  • Me alegró ver que el OP implementó bien un toggle de 3 estados
  • Me habría parecido más divertido si los niveles se aplicaran dinámicamente mientras uno va bajando con el scroll
    • O si no, también estaría bien que el lector pudiera elegir el nivel por su cuenta en puntos adecuados de la página
  • A mí me parece que son 8 niveles, ¿no?
  • Esto sí se sintió muy 2024
  • Lo primero que se me vino a la cabeza en esta situación fue, por supuesto, xkcd 3227