Las seis etapas del modo oscuro (2024)
(cssence.com)- Desde funciones nativas del navegador hasta media queries de JavaScript, se organiza una clasificación gradual de 8 niveles para ampliar progresivamente el alcance de implementación del modo oscuro
- La forma más simple consiste en seguir la preferencia de esquema de color del usuario solo con declarar
<meta name="color-scheme" content="light dark">ocolor-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 colores, sino también imágenes y sombras - También es posible crear un selector que no dependa solo de la configuración del sistema del usuario y ofrezca tres opciones: Automático, light y dark; además, se puede determinar el tema con
:has()y el elemento meta real - Incluye las limitaciones de accesibilidad de Safari y observaciones sobre el comportamiento de
prefers-color-schemeal imprimir, mostrando que con funciones recientes de CSS ya es fácil incorporar 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 con solo añadir
<meta name="color-scheme" content="light dark">en el head del documento el navegador empieza a seguir la preferencia de esquema de color del usuario - En teoría, el orden de los elementos del atributo
contenttiene significado, y los usuarios que no hayan indicado una preferencia de esquema de color reciben el primer valor de la lista separada por espacios - Como la configuración actual de los sistemas operativos no ofrece una opción para no elegir esquema de color, en la práctica esto 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 considerar la preferencia del usuario - Esta etiqueta meta cumple en cierta medida el papel de una vía del lado de HTML equivalente al enfoque CSS de la siguiente etapa
- Incluso sin una sola línea de CSS se puede activar la distinción entre light/dark, y con solo añadir
-
Level 2: Basic
- En CSS, se puede aplicar la distinción entre modo claro/oscuro con la declaración
html { color-scheme: light dark; } - Si ya existe una etiqueta meta en el DOM, esta declaración no es necesaria; si se puede controlar el HTML, se recomienda usar la meta etiqueta para que el navegador conozca 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 añade CSS, pero limitándose principalmente al uso de CSS system colors, es posible 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-schemetambién puede establecerse fuera del elemento raíz, lo que abre espacio para usos adicionales
- En CSS, se puede aplicar la distinción entre modo claro/oscuro con la declaración
-
Level 3: Benign
- Con la función de color
light-dark()de CSS, añadida relativamente hace poco, se pueden hacer ajustes simples de modo claro/oscuro - En el ejemplo se usa como
background-color: light-dark(black, white);ycolor: 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 directamente o custom properties que se interpreten como color
- En todo el artículo, esta es la única etapa que, al momento de escribirse, todavía no tiene suficiente soporte de navegadores
- Con la función de color
-
Level 4: Bold
- Se puede implementar el cambio a modo oscuro con la media query tradicional
@media (prefers-color-scheme: dark) - Ya sea consultando
lightodark, permite el máximo nivel de personalización, no limitado a simples cambios de color - También permite ajustes como desaturar imágenes con filtros en modo oscuro o reemplazar sombras de cajas por contornos
- Se puede implementar el cambio a modo oscuro con la media query tradicional
-
Level 5: Bisectional
- Las media queries también pueden usarse en HTML, colocándolas en el atributo
mediade un elementolinkpara separar hojas de estilo por esquema - Como ejemplo, se propone conectar
light.cssydark.cssrespectivamente aprefers-color-scheme: lightyprefers-color-scheme: dark - Cuando el alcance de personalización es grande, una configuración con archivos dedicados resulta adecuada, y el navegador puede ignorar el archivo CSS que no coincida con la consulta, reduciendo en uno los archivos a descargar
- Las media queries también pueden usarse en HTML, colocándolas en el atributo
-
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 el esquema es claro u oscuro y realizar el procesamiento deseado en función del resultado
- En una implementación real, no hace falta ceñirse a una sola técnica de las etapas anteriores, sino que se pueden combinar
- En JavaScript, se puede usar la media query de esquema de color con
Selector del usuario y patrones avanzados
-
Level 7: Beyond
- No es necesario depender solo de la preferencia del sistema del usuario; también se puede construir un selector de esquema de color
- Este selector no es un simple booleano, ya que necesita un modo Automático como valor inicial por defecto que siga
prefers-color-scheme - Si se añade ese selector encima, el usuario puede elegir entre tres modos: Automático, light y dark
-
Level 8: Beguiling
- Al implementar el selector de Level 7, normalmente se suele añadir una clase
.darko un atributo comodata-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 CSS como--color-bgy--color-textcon valores del modo oscuro - Así es posible determinar el tema a partir del elemento meta real sin necesidad de clases ni atributos de datos adicionales
- Al implementar el selector de Level 7, normalmente se suele añadir una clase
Debate adicional y observaciones
-
Observación en CSS Naked Day
- Tras eliminar los estilos, en casi todos los sitios visitados se hizo evidente la ausencia de modo oscuro, y eso llevó a distinguir las etapas del modo oscuro
- También se menciona que, al construir un sitio nuevo desde cero y escribir estilos nuevos, con las funciones recientes de CSS resulta muy fácil incorporar de base 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, retirando la meta etiqueta y usando solo el esquema claro
- Después se volvió a añadir la meta etiqueta, pero reconociendo que en usuarios de versiones antiguas de Safari podría haber una degradación de accesibilidad
- También se confirma la ausencia de bordes visibles en cuadros de texto dentro del 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 mantener suficiente estilo también en futuros CSS Naked Day
-
Impresión y la condición
screen and- Se menciona que en el ejemplo Bisectional se usó
screen and ...con la intención de excluir impresoras como destino - 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 pruebas reales, incluso imprimiendo con el modo oscuro del sistema activado, solo salieron texto negro y papel blanco, observándose que los navegadores no aplican esos estilos oscuros al imprimir
- En pruebas adicionales, en la vista previa de impresión
prefers-color-schemesiempre se reportó como light, confirmado en Firefox y Chromium - Se incluye un comentario en tono de broma sobre que sería una lástima tener una impresora que use papel negro y tinta blanca
- Se menciona que en el ejemplo Bisectional se usó
1 comentarios
Comentarios de Hacker News
userContent.cssde Firefox funciona bastante bien