La propiedad color-scheme
de CSS y la etiqueta meta correspondiente permiten que los desarrolladores habiliten los valores predeterminados específicos del tema de la hoja de estilo del usuario-agente en sus páginas.
Fondo
La función de medios prefers-color-scheme
de preferencia del usuario
La función de medios de preferencia del usuario prefers-color-scheme
les brinda a los desarrolladores un control total sobre la apariencia de sus páginas.
Si no lo conoces, lee mi artículo prefers-color-scheme
: Hello darkness, my old friend, en el que documenté todo lo que sé sobre la creación de experiencias increíbles en modo oscuro.
Una pieza del rompecabezas que solo se mencionó brevemente en el artículo es la propiedad color-scheme
de CSS y la etiqueta meta correspondiente con el mismo nombre.
Ambas facilitan tu vida como desarrollador, ya que te permiten habilitar en tu página los valores predeterminados específicos del tema de la hoja de estilo del agente de usuario, como, por ejemplo, los controles de formulario, las barras de desplazamiento y los colores del sistema CSS.
Al mismo tiempo, esta función evita que los navegadores apliquen transformaciones por su cuenta.
Navegadores compatibles
prefers-color-scheme
color-scheme
La hoja de estilo del usuario-agente
Antes de continuar, permítanme describir brevemente qué es una hoja de estilo de usuario-agente. La mayoría de las veces, puedes pensar en la palabra usuario-agente (UA) como una forma elegante de decir navegador. La hoja de estilo de UA determina el aspecto predeterminado de una página. Como lo sugiere su nombre, una hoja de estilo de UA es algo que depende del UA en cuestión. Puedes consultar la hoja de estilo de UA de Chrome (y de Chromium) y compararla con la de Firefox o Safari (y de WebKit). Por lo general, las hojas de estilo de UA coinciden en la mayoría de los aspectos. Por ejemplo, todos hacen que los vínculos sean azules, el texto general negro y el color de fondo blanco, pero también hay diferencias importantes (y, a veces, molestas), por ejemplo, cómo diseñan los controles de formulario.
Analiza con más detalle la hoja de estilo del agente de usuario de WebKit y lo que hace con respecto al modo oscuro.
(Realiza una búsqueda de texto completo de "oscuro" en la hoja de diseño).
El valor predeterminado que proporciona la hoja de diseño cambia según si el modo oscuro está activado o desactivado. Para ilustrar esto, aquí se muestra una regla CSS de este tipo que usa la seudoclase :matches
y variables internas de WebKit, como -apple-system-control-background
, así como la directiva del preprocesador interno de WebKit #if defined
:
input,
input:matches([type="password"], [type="search"]) {
-webkit-appearance: textfield;
#if defined(HAVE_OS_DARK_MODE_SUPPORT) &&
HAVE_OS_DARK_MODE_SUPPORT
color: text;
background-color: -apple-system-control-background;
#else
background-color: white;
#endif
/* snip */
}
Observarás algunos valores no estándar para las propiedades color
y background-color
anteriores.
Ni text
ni -apple-system-control-background
son colores CSS válidos.
Son colores semánticos internos de WebKit.
Resulta que CSS estandarizó los colores semánticos del sistema.
Se especifican en el módulo de color CSS nivel 4.
Por ejemplo, Canvas
(que no se debe confundir con la etiqueta <canvas>
) se usa para el fondo del contenido o los documentos de la aplicación, mientras que CanvasText
se usa para el texto del contenido o los documentos de la aplicación.
Ambos van de la mano y no deben usarse de forma aislada.
Las hojas de estilo de UA pueden usar sus propios colores patentados o los colores estandarizados del sistema semántico para determinar cómo se deben renderizar los elementos HTML de forma predeterminada.
Si el sistema operativo está configurado en modo oscuro o usa un tema oscuro, CanvasText
(o text
) se establecería de forma condicional en blanco, y Canvas
(o -apple-system-control-background
) se establecería en negro.
Luego, la hoja de estilo del UA asigna el siguiente CSS solo una vez y abarca el modo claro y el oscuro.
/**
Not actual UA stylesheet code.
For illustrative purposes only.
*/
body {
color: CanvasText;
background-color: Canvas
}
La propiedad color-scheme
de CSS
La especificación del módulo de ajuste de color CSS nivel 1 introduce un modelo y controles sobre el ajuste automático de color por parte del agente de usuario con el objetivo de controlar las preferencias del usuario, como el modo oscuro, el ajuste de contraste o esquemas de color deseados específicos.
La propiedad color-scheme
definida allí permite que un elemento indique con qué combinaciones de colores se puede renderizar.
Estos valores se negocian con las preferencias del usuario, lo que da como resultado un esquema de color elegido que afecta elementos de la interfaz de usuario (IU), como los colores predeterminados de los controles de formulario y las barras de desplazamiento, así como los valores utilizados de los colores del sistema CSS.
Se admiten los siguientes valores:
normal
Indica que el elemento no conoce los esquemas de color en absoluto, por lo que se debe renderizar con el esquema de color predeterminado del navegador.[ light | dark ]+
Indica que el elemento conoce y puede controlar los esquemas de color enumerados, y expresa una preferencia ordenada entre ellos.
En esta lista, light
representa un esquema de color claro, con colores de fondo claros y colores de primer plano oscuros, mientras que dark
representa lo contrario, con colores de fondo oscuros y colores de primer plano claros.
En el caso de todos los elementos, la renderización con un esquema de color debe hacer que los colores utilizados en toda la IU proporcionada por el navegador para el elemento coincidan con la intención del esquema de color. Algunos ejemplos son las barras de desplazamiento, los subrayados de corrección ortográfica, los controles de formularios, etcétera.
En el elemento :root
, la renderización con un esquema de colores también debe afectar el color de la superficie del lienzo (es decir, el color de fondo global), el valor inicial de la propiedad color
y los valores usados de los colores del sistema, y también debe afectar las barras de desplazamiento de la ventana gráfica.
/*
The page supports both dark and light color schemes,
and the page author prefers dark.
*/
:root {
color-scheme: dark light;
}
La metaetiqueta color-scheme
Para respetar la propiedad color-scheme
de CSS, primero se debe descargar el CSS (si se hace referencia a él a través de <link rel="stylesheet">
) y analizarlo.
Para ayudar a los agentes de usuario a renderizar el fondo de la página con el esquema de color deseado de inmediato, también se puede proporcionar un valor color-scheme
en un elemento <meta name="color-scheme">
.
<!--
The page supports both dark and light color schemes,
and the page author prefers dark.
-->
<meta name="color-scheme" content="dark light">
Combinación de color-scheme
y prefers-color-scheme
Dado que tanto la metaetiqueta como la propiedad CSS (si se aplica al elemento :root
) generan el mismo comportamiento, siempre recomiendo especificar el esquema de color a través de la metaetiqueta para que el navegador pueda adoptar el esquema preferido más rápido.
Si bien para las páginas de referencia absolutas no se necesitan reglas de CSS adicionales, en el caso general, siempre debes combinar color-scheme
con prefers-color-scheme
.
Por ejemplo, el color CSS propietario de WebKit -webkit-link
, que usan WebKit y Chrome para el azul clásico de los vínculos rgb(0,0,238)
, tiene una proporción de contraste insuficiente de 2.23:1 sobre un fondo negro y no cumple con los requisitos de la WCAG AA ni de la WCAG AAA.
Abrí errores para Chrome, WebKit y Firefox, así como un problema de metadatos en el estándar de HTML para solucionar este problema.
Interacción con prefers-color-scheme
La interacción de la propiedad color-scheme
de CSS y la etiqueta meta correspondiente con la función de medios de preferencia del usuario prefers-color-scheme
puede parecer confusa al principio.
De hecho, se complementan muy bien.
Lo más importante que debes comprender es que color-scheme
determina exclusivamente la apariencia predeterminada, mientras que prefers-color-scheme
determina la apariencia que se puede diseñar.
Para que esto quede más claro, supongamos la siguiente página:
<head>
<meta name="color-scheme" content="dark light">
<style>
fieldset {
background-color: gainsboro;
}
@media (prefers-color-scheme: dark) {
fieldset {
background-color: darkslategray;
}
}
</style>
</head>
<body>
<p>
Lorem ipsum dolor sit amet, legere ancillae ne vis.
</p>
<form>
<fieldset>
<legend>Lorem ipsum</legend>
<button type="button">Lorem ipsum</button>
</fieldset>
</form>
</body>
El código CSS intercalado en la página establece el background-color
del elemento <fieldset>
en gainsboro
en el caso general y en darkslategray
si el usuario prefiere un esquema de color dark
según la función de medios de preferencia del usuario prefers-color-scheme
.
A través del elemento <meta name="color-scheme" content="dark light">
, la página le indica al navegador que admite un tema oscuro y uno claro, con una preferencia por el tema oscuro.
Según si el sistema operativo está configurado en modo oscuro o claro, toda la página aparecerá en claro sobre oscuro o viceversa, según la hoja de estilo del agente de usuario. No se incluye CSS adicional proporcionado por el desarrollador para cambiar el texto del párrafo ni el color de fondo de la página.
Observa cómo cambia el background-color
del elemento <fieldset>
según si el modo oscuro está habilitado, siguiendo las reglas de la hoja de estilo intercalada proporcionada por el desarrollador en la página.
Puede ser gainsboro
o darkslategray
.

background-color
del elemento <fieldset>
es gainsboro
, según la hoja de diseño para desarrolladores intercalada.

background-color
del elemento <fieldset>
es darkslategray
, según la hoja de diseño para desarrolladores intercalada.
La apariencia del elemento <button>
se controla con la hoja de estilo del agente de usuario.
Su color
se establece en el color del sistema ButtonText
, y su background-color
y los cuatro border-color
se establecen en el color del sistema ButtonFace
.

background-color
y los distintos border-color
s se establecen en el color del sistema ButtonFace.
Ahora observa cómo cambia el border-color
del elemento <button>
.
El valor calculado para los interruptores border-top-color
y border-bottom-color
cambia de rgba(0, 0, 0, 0.847)
(negruzco) a rgba(255, 255, 255, 0.847)
(blanquecino), ya que el agente de usuario actualiza ButtonFace
de forma dinámica según el esquema de color.
Lo mismo se aplica al color
del elemento <button>
, que se establece en el color del sistema correspondiente ButtonText
.

border-top-color
y border-bottom-color
, que se establecen en ButtonFace
en la hoja de estilo del usuario-agente, ahora son rgba(0, 0, 0, 0.847)
.

border-top-color
y border-bottom-color
que se establecen en ButtonFace
en la hoja de estilo del usuario-agente ahora son rgba(255, 255, 255, 0.847)
.
Demostración
Puedes ver los efectos de color-scheme
aplicados a una gran cantidad de elementos HTML en una demostración en Glitch.
La demostración muestra deliberadamente el incumplimiento de los niveles AA y AAA de las WCAG con los colores de los vínculos que se mencionan en la advertencia anterior.

color-scheme: light
.

color-scheme: dark
.
Observa el incumplimiento de las WCAG AA y WCAG AAA
con los colores de los vínculos.
Agradecimientos
Rune Lillesveen implementó la propiedad de CSS color-scheme
y la etiqueta meta correspondiente.
Rune también es coeditor de la especificación del módulo de ajuste de color de CSS nivel 1.
Imagen de héroe de Philippe Leone en Unsplash.