A propriedade CSS color-scheme
e a metatag correspondente
permitem que os desenvolvedores ativem as páginas nos padrões específicos do tema da folha de estilo do user agent.
Contexto
O recurso de mídia de preferência do usuário prefers-color-scheme
O
recurso de mídia de preferência do usuário
prefers-color-scheme
oferece aos desenvolvedores controle total sobre a aparência das páginas.
Caso não conheça esse recurso, leia meu artigo
prefers-color-scheme
: Hello Dark, my old amigo (link em inglês),
em que documentei tudo o que sei sobre a criação de experiências incríveis no modo escuro.
Uma peça de quebra-cabeça que foi mencionada rapidamente no artigo é
a propriedade CSS color-scheme
e a metatag correspondente com o mesmo nome.
Ambos facilitam sua vida de desenvolvedor, permitindo que você ative sua página em padrões específicos do tema da folha de estilo do user agent, como, por exemplo, controles de formulário, barras de rolagem e cores do sistema CSS.
Ao mesmo tempo, esse recurso impede que os navegadores apliquem transformações por conta própria.
Suporte ao navegador
prefers-color-scheme
color-scheme
A folha de estilo do user agent
Antes de continuar, vou descrever brevemente o que é uma folha de estilo do user agent. Na maioria das vezes, você pode pensar na palavra user agent (UA) como uma forma sofisticada de dizer browser. A folha de estilo do UA determina a aparência padrão de uma página. Como o nome sugere, uma folha de estilo do UA é algo que depende do UA em questão. Você pode analisar a folha de estilo do UA do Chrome (e do Chromium) e compará-la à do Firefox ou do Safari (e do WebKit). Normalmente, as folhas de estilo do UA concordam com a maioria dos itens. Por exemplo, todos eles deixam links azuis, texto geral em preto e cor de fundo branca, mas também há diferenças importantes (e às vezes irritantes), por exemplo, a forma como eles estilizam controles de formulários.
Analise mais detalhadamente a folha de estilo do UA do WebKit e o que ela faz em relação ao modo escuro.
(Pesquise o texto completo do termo "escuro" na folha de estilo.)
O padrão fornecido pela folha de estilo muda com base na ativação ou desativação do modo escuro.
Para ilustrar isso, veja uma regra CSS que usa a pseudoclasse
:matches
e as variáveis internas do WebKit, como -apple-system-control-background
,
bem como a diretiva do pré-processador interna do 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 */
}
Você vai notar alguns valores não padrão para as propriedades color
e background-color
acima.
text
e -apple-system-control-background
não são cores CSS válidas.
Elas são cores semânticas internas do WebKit.
Acontece que o CSS tem cores padronizadas para o sistema semântico.
Elas são especificadas no
Módulo de cores CSS nível 4.
Por exemplo,
Canvas
(que não deve ser confundido com a tag <canvas>
)
é para o segundo plano do conteúdo ou documentos do aplicativo,
enquanto
CanvasText
é para texto no conteúdo ou documentos do aplicativo.
Os dois funcionam juntos e não devem ser usados isoladamente.
As folhas de estilo do UA podem usar cores próprias ou padronizadas do sistema semântico para determinar como os elementos HTML serão renderizados por padrão.
Se o sistema operacional estiver definido para o modo escuro ou usar um tema escuro,
CanvasText
(ou text
) será definido condicionalmente como branco,
e Canvas
(ou -apple-system-control-background
) será definido como preto.
Em seguida, a folha de estilo do UA atribui o CSS a seguir apenas uma vez e abrange os modos claro e escuro.
/**
Not actual UA stylesheet code.
For illustrative purposes only.
*/
body {
color: CanvasText;
background-color: Canvas
}
A propriedade CSS color-scheme
A especificação do Módulo de ajuste de cor CSS nível 1 apresenta um modelo e controla o ajuste automático de cor do user agent com o objetivo de lidar com as preferências do usuário, como modo escuro, ajuste de contraste ou esquemas de cores específicos.
A propriedade color-scheme
definida aqui permite que um elemento indique
com quais esquemas de cores ele se sente confortável para ser renderizado.
Esses valores são negociados com as preferências do usuário, resultando em um esquema de cores escolhido
que afeta aspectos da interface do usuário (interface), como as cores padrão dos controles de formulário
e as barras de rolagem, bem como os valores usados das cores do sistema CSS.
No momento, os seguintes valores são permitidos:
normal
indica que o elemento não reconhece esquemas de cores e, portanto, precisa ser renderizado com o esquema de cores padrão do navegador.[ light | dark ]+
indica que o elemento está ciente e pode processar os esquemas de cores listados e expressa uma preferência ordenada entre eles.
Nesta lista, light
representa um esquema de cores claras,
com cores de fundo claras e cores de primeiro plano escuras,
enquanto dark
representa o oposto, com cores de fundo escuras e de primeiro plano claros.
Para todos os elementos, a renderização com um esquema de cores precisa fazer com que as cores usadas em todas as interfaces fornecidas pelo navegador para o elemento correspondam à intent do esquema de cores. Por exemplo, barras de rolagem, sublinhados de verificação ortográfica, controles de formulário etc.
No elemento :root
, a renderização com um esquema de cores
também precisa afetar a cor da superfície da tela (ou seja, a cor global do plano de fundo),
o valor inicial da propriedade color
e os valores usados das cores do sistema,
além de afetar as barras de rolagem da janela de visualização.
/*
The page supports both dark and light color schemes,
and the page author prefers dark.
*/
:root {
color-scheme: dark light;
}
A metatag color-scheme
Para honrar a propriedade CSS color-scheme
, primeiro é necessário fazer o download do CSS (se ele for referenciado por <link rel="stylesheet">
) e ser analisado.
Para ajudar os user agents a renderizar o plano de fundo da página com o esquema de cores desejado imediatamente,
um valor color-scheme
também pode ser fornecido em um
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">
Combinar color-scheme
e prefers-color-scheme
Como a metatag e a propriedade CSS (se aplicadas ao elemento :root
) resultarem no mesmo comportamento, é sempre recomendável especificar o esquema de cores usando a metatag para que o navegador adote o esquema preferido mais rapidamente.
Ainda que, para páginas de referência absoluta, nenhuma outra regra CSS seja necessária.
No caso geral, sempre combine color-scheme
com prefers-color-scheme
.
Por exemplo, a cor reservada do CSS do WebKit -webkit-link
, usada pelo WebKit e pelo Chrome para o link clássico azul rgb(0,0,238)
, tem uma taxa de contraste insuficiente de 2.23:1 em um fundo preto e falha nos requisitos das WCAG AA e da WCAG AAA.
Abri bugs para o Chrome, o WebKit e o Firefox, assim como um problema meta no HTML padrão para corrigir isso.
Interação com prefers-color-scheme
A interação da propriedade CSS color-scheme
e da metatag correspondente
com o recurso de mídia de preferência do usuário prefers-color-scheme
pode parecer confusa a princípio.
Na verdade, eles funcionam muito bem juntos.
O mais importante é que o color-scheme
determina exclusivamente a aparência padrão,
enquanto prefers-color-scheme
determina a aparência estilizável.
Para deixar isso mais claro, considere a seguinte 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>
O código CSS inline na página
define o background-color
do elemento <fieldset>
como gainsboro
no caso geral
e como darkslategray
se o usuário preferir um esquema de cores dark
de acordo com o recurso de mídia de preferência do usuário prefers-color-scheme
.
Usando o elemento <meta name="color-scheme" content="dark light">
,
a página informa ao navegador que oferece suporte a um tema escuro e um
claro, com preferência por um tema escuro.
Dependendo de o sistema operacional estar definido no modo escuro ou claro, a página inteira aparecerá clara no escuro ou vice-versa, com base na folha de estilo do user agent. Não há outro CSS fornecido pelo desenvolvedor envolvido para alterar o texto do parágrafo ou a cor de fundo da página.
Observe como o background-color
do elemento <fieldset>
muda
com base na ativação do modo escuro, seguindo as regras
na folha de estilo in-line fornecida pelo desenvolvedor na página.
É gainsboro
ou darkslategray
.
![Uma página no modo claro.](https://web.dev/static/articles/color-scheme/image/a-page-light-mode-20033c5b52e57.png?authuser=5&hl=pt)
background-color
do elemento <fieldset>
é gainsboro
de acordo com a folha de estilo inline do desenvolvedor.
![Uma página no modo escuro.](https://web.dev/static/articles/color-scheme/image/a-page-dark-mode-db72ce14278ec.png?authuser=5&hl=pt)
background-color
do elemento <fieldset>
é darkslategray
de acordo com a folha de estilo inline do desenvolvedor.
A aparência do elemento <button>
é controlada pela folha de estilo do user agent.
O color
está definido como a cor do sistema
ButtonText
, e o background-color
e os quatro border-color
s estão definidos como a cor do sistema
ButtonFace
.
![Uma página do modo claro que usa a propriedadeButtonFace.](https://web.dev/static/articles/color-scheme/image/a-light-mode-page-uses-2d1dbd77e94d4.png?authuser=5&hl=pt)
background-color
e os vários
border-color
s são definidos com a cor do sistema ButtonFace.
Agora, observe como o border-color
do elemento <button>
muda.
O valor computed para border-top-color
e border-bottom-color
muda de rgba(0, 0, 0, 0.847)
(preto) para rgba(255, 255, 255, 0.847)
(whitish),
já que o user agent atualiza ButtonFace
dinamicamente com base no esquema de cores.
O mesmo se aplica ao color
do elemento <button>
,
que é definido como a cor correspondente do sistema ButtonText
.
![Mostrando que os valores de cor calculados correspondem ao botãoFace.](https://web.dev/static/articles/color-scheme/image/showing-the-computed-col-b5a5bb27a14d7.png?authuser=5&hl=pt)
border-top-color
e border-bottom-color
que estão definidos como ButtonFace
na folha de estilo do user agent agora são rgba(0, 0, 0, 0.847)
.
![Mostrando que os valores de cor calculados ainda correspondem aoButtonFace no modo escuro.](https://web.dev/static/articles/color-scheme/image/showing-the-computed-col-fbfce1c6513a9.png?authuser=5&hl=pt)
border-top-color
e border-bottom-color
que estão definidos como ButtonFace
na folha de estilo do user agent agora são rgba(255, 255, 255, 0.847)
.
Demonstração
É possível conferir os efeitos de color-scheme
aplicados a um grande número de elementos HTML
em uma demonstração do Glitch.
A demonstração mostra intencionalmente a violação
das WCAG AA e das WCAG AAA com as cores de link mencionadas no aviso acima.
![A demonstração no modo claro.](https://web.dev/static/articles/color-scheme/image/the-demo-while-light-mod-8d16b35fd6de9.png?authuser=5&hl=pt)
color-scheme: light
.
![A demonstração no modo escuro.](https://web.dev/static/articles/color-scheme/image/the-demo-while-dark-mode-9f130b7310353.png?authuser=5&hl=pt)
color-scheme: dark
.
Observe a
violação
das WCAG AA e as WCAG AAA com as cores do link.
Agradecimentos
A propriedade CSS color-scheme
e a metatag correspondente foram implementadas por Rune Lillesveen.
Rune também é coeditora da especificação CSS Color Adjustment Module Level 1.
Imagem principal de
Philippe Leone
no Unsplash (links em inglês).