Temificación en 2025: del modo oscuro a color-scheme y light-dark()
Tabla de contenido
Hace algunos años irrumpió con fuerza el dark-mode –modo oscuro–, que parecía originalmente ideado para reducir la fatiga visual del usuario –porque la web, al fin y al cabo, es una red de documentos pensada para leerse sobre pantallas luminosas–, pero rápidamente se volvió muy popular por su sobria estética y elegante frescura. Compañías como Google o Facebook y sistemas operativos como iOS o Android pronto lo adoptaron y la tendencia se expandió ampliamente y pasó a ser un recurso de diseño más.
Y muchos sites –este incluido– tenían su versión dark y el usuario podía escoger la apariencia y todo era genial. Esto supuso algunos retos técnicos, como diseñar una paleta de color lo suficientemente sólida para soportar ambas versiones, o persistir la decisión del usuario, pero era al mismo tiempo excitante.
Para su implementación, lo mejor era aprovechar la cascada –la C de CSS– y añadir una clase o atributo al elemento raíz, como html o body como repasamos en el artículo Cómo crear diferentes themes en css, pero hoy podemos simplificar esa aproximación gracias a nuevas capacidades del lenguaje como prefers-color-scheme o color-scheme y la función light-dark.
En las preferencias del sistema o del navegador, el usuario puede elegir entrelightodarksiendolightel valor por defecto.
prefers-color-scheme
Es una directiva de tipo @media que nos permite conocer la preferencia del esquema de color del usuario, y podemos por tanto, reaccionar a su valor.
@media (prefers-color-scheme: light) {
:root {
--bg-color: #ffffff;
--front-color: #ff0066;
}
}
@media (prefers-color-scheme: dark) {
:root {
--bg-color: #171115;
--front-color: #ddccbb;
}
}
Podemos ser muy explícitos y asignar valores a las variables para cada versión o declarar un valor por defecto y sobreescribir las variables para su contrario, el resultado es el mismo. Lo importante es tener una paleta de color bien estructurada y que sea fácil de canalizar a través de custom properties y poder reasignarlas para cada variante, esa es la idea, olvidándonos de detectar, guardar y persistir la preferencia del usuario. Además, cualquier cambio en el esquema de color se aplica en tiempo real.
Imágenes
Si tu site es todo texto y elementos vectoriales no habrá piedras en el camino, pero quizá tengas imágenes que no contrastan bien con ambos fondos. Para estos casos, es muy útil utilizar picture. Las etiquetas source aceptan el atributo media, que es igualito a @media de CSS, por lo que puedes seguir usando prefers-color-scheme así <source srcset="alternative.png" media="(prefers-color-scheme: dark)" />
Demo
color-scheme
Esta propiedad le indica al navegador el esquema de color para el que está preparado el documento o un elemento concreto, y cómo deben renderizarse los elementos del sistema (formularios, scrollbars, autofill, etc.)
Es interesante porque puedes hacer el control global o muy granular.
:root {
color-scheme: light dark;
}
.element {
color-scheme: light dark;
}
Merece especial atención la keyword only porque sirve para bloquear un esquema concreto de manera que el navegador no va a cambiarlo.
form {
color-scheme: only dark;
}
Demo
Existe una alternativa a declarar el esquema de color en :root y es hacerlo en el head del documento con la etiqueta <meta name="color-scheme" content="dark light" />
Por otro lado, color-scheme se puede combinar con prefers-color-scheme pero personalmente me gusta más combinarla con la función de color light-dark()
light-dark
Es una función que acepta dos parámetros de tipo color. El color declarado en primer lugar se aplica si el esquema de color es light o está sin definir y el segundo si la preferencia es dark.
/* Para que light-dark() funcione correctamente, es necesario declarar previamente color-scheme: light dark */
:root {
color-scheme: light dark;
}
.element {
color: light-dark(cyan, lime);
}
Por supuesto, se puede utilizar en combinación con variables
.element {
color: light-dark(var(--color-light), var(--color-dark));
}
Este enfoque es más directo y explícito que el de prefers-color-scheme, y además es muy flexible, porque se puede aplicar a cualquier elemento de forma independiente, y al aceptar cualquier color, podemos crear excepciones facilmente. Como contra diremos que, aunque tengamos la declaración de las variables centralizadas en :root vamos a tener la implementación repartida por el código.
Demo
If
Si lo piensas light-dark luce como un if/else así que como alternativa podríamos usar if() aunque como el soporte aún es limitado, no me lo voy a tomar muy en serio.
Esta función nos permite aplicar un valor u otro en función del resultado de un test de style, media o feature así que podríamos hacer algo así
.element {
color: if(media(prefers-color-scheme: dark): purple; else: #f06);
}
Parece que es escribir demasiado y que cualquiera de los enfoques anteriores es mejor, pero es muy interesante y potente.
Demo
Conclusión
Como CSS es un lenguaje en construcción, es capaz de adaptarse a nuestras demandas y necesidades con rapidez, lo que en mi opinión, es la clave de su éxito. Qué enfoque utilices dependerá de tus necesidades.
A veces los focos iluminan las características más brillantes, como view transitions o if() dejando a otras en zona de sombra, pero que pueden resultar igual o más interesantes. En este caso, color-scheme y light-dark me parece que resuelven un problema muy complejo de forma muy sencilla.
Por otro lado, aunque sólo hemos hablado de implementar, es esencial planificar y diseñar una paleta que funcione bien, sin esa base, el resultado puede ser inconsistente o caótico.
Recursos
comments powered by DisqusSi te ha parecido interesante
Tanto si tienes alguna duda o te apetece charlar sobre este tema, así como si el contenido te parece interesante o crees que pdemos hacer algo juntos, no dudes en ponerte en contacto con nosotros a través del email hola@mamutlove.com