Os seis níveis do modo escuro (2024)
(cssence.com)- Organização de uma classificação em 8 níveis que amplia gradualmente o escopo de implementação do modo escuro, dos recursos nativos do navegador até media queries em JavaScript
- A forma mais simples é configurar o site para seguir a preferência de esquema de cores do usuário apenas com a declaração
<meta name="color-scheme" content="light dark">oucolor-scheme: light dark - Em níveis mais altos, a função
light-dark(),@media (prefers-color-scheme: dark)e stylesheets separadas por esquema permitem ajustar amplamente não só cores, mas também imagens e sombras - Também é possível criar um seletor que não siga apenas a configuração do sistema do usuário, oferecendo três opções: Automatic, light, dark, e identificar o tema com base em
:has()e no elemento meta real - Inclui as limitações de acessibilidade do Safari e observações sobre o comportamento de
prefers-color-schemena impressão, mostrando que, mesmo só com recursos CSS recentes, ficou muito mais fácil embutir os modos claro e escuro
Implementação do modo escuro por níveis
-
Level 1: Barebone
- Mesmo sem uma linha de CSS, é possível ativar a distinção entre light/dark; basta adicionar
<meta name="color-scheme" content="light dark">noheaddo documento para que o navegador passe a seguir a preferência de esquema de cores do usuário - A ordem dos itens no atributo
contentteoricamente tem significado, e usuários que não definirem preferência de esquema de cores receberão o primeiro valor da lista separada por espaços - Como as configurações atuais dos sistemas operacionais não têm uma opção de não escolher um esquema de cores, na prática isso acaba resultando em um esquema que coincide com a configuração do sistema
- Também é possível definir apenas um único valor em
content; nesse caso, o esquema correspondente é forçado, sem considerar a preferência do usuário - Essa meta tag cumpre, em certa medida, o papel de uma abordagem HTML correspondente ao método em CSS da etapa seguinte
- Mesmo sem uma linha de CSS, é possível ativar a distinção entre light/dark; basta adicionar
-
Level 2: Basic
- Em CSS, é possível aplicar a distinção entre modo claro/escuro com a declaração
html { color-scheme: light dark; } - Se já houver uma meta tag no DOM, essa declaração não é necessária; se você controla o HTML, recomenda-se usar a meta tag, porque o navegador pode conhecer a instrução antes mesmo de fazer o parsing do CSS
- Ambas as abordagens permitem aproveitar os estilos padrão do user agent e o respectivo modo claro/escuro incluído neles
- Se você adicionar CSS aqui, mas se limitar principalmente ao uso de CSS system colors, já é possível obter um design bastante organizado
- Diferentemente da meta tag, que sempre se aplica ao documento inteiro, a declaração CSS
color-schemetambém pode ser definida fora do elemento raiz, o que abre espaço para usos adicionais
- Em CSS, é possível aplicar a distinção entre modo claro/escuro com a declaração
-
Level 3: Benign
- É possível fazer ajustes simples de modo claro/escuro com a função de cor
light-dark()do CSS, adicionada relativamente recentemente - No exemplo, ela é usada como
background-color: light-dark(black, white);ecolor: light-dark(white, black);; o primeiro argumento é aplicado no modo claro e o segundo no modo escuro - Os argumentos podem ser cores literais ou custom properties interpretadas como cores
- Em todo o artigo, esta é a única etapa que, no momento da escrita, ainda não tinha suporte de navegadores suficiente
- É possível fazer ajustes simples de modo claro/escuro com a função de cor
-
Level 4: Bold
- É possível implementar a troca para modo escuro com a media query tradicional
@media (prefers-color-scheme: dark) - Consultando
lightoudark, dá para alcançar o máximo nível de customização, sem ficar limitado a simples trocas de cor - Também é possível, por exemplo, dessaturar imagens com filtros no modo escuro ou substituir box shadows por contornos
- É possível implementar a troca para modo escuro com a media query tradicional
-
Level 5: Bisectional
- Media queries também podem ser usadas no HTML, inseridas no atributo
mediade elementoslink, permitindo separar stylesheets por esquema - O exemplo mostra
light.cssedark.cssligados respectivamente aprefers-color-scheme: lighteprefers-color-scheme: dark - Quando o escopo de customização é grande, uma estrutura com arquivos dedicados faz sentido, e o navegador pode ignorar o arquivo CSS que não corresponde à consulta, reduzindo em um o total de downloads necessários
- Media queries também podem ser usadas no HTML, inseridas no atributo
-
Level 6: Ballistic
- Em JavaScript, é possível usar a media query de esquema de cores com
window.matchMedia('(prefers-color-scheme:dark)') - Assim como em outras media queries, é possível consultar se o esquema é claro ou escuro e executar o processamento desejado com base no resultado
- Em implementações reais, não é preciso ficar preso a apenas uma das técnicas das etapas anteriores; elas podem ser combinadas
- Em JavaScript, é possível usar a media query de esquema de cores com
Seletor do usuário e padrões avançados
-
Level 7: Beyond
- Não é necessário depender apenas da preferência do sistema; também é possível criar um color scheme switcher
- Esse seletor não é um simples booleano; ele precisa de um modo Automatic que, como valor inicial, siga
prefers-color-scheme - Ao adicionar o seletor por cima disso, o usuário pode escolher entre três modos: Automatic, light, dark
-
Level 8: Beguiling
- Ao implementar o seletor do Level 7, é comum adicionar uma classe
.darkao HTML ou um atributo comodata-theme="dark" - Em vez disso, é possível usar
:has()para consultar diretamente a existência real de<meta name="color-scheme" content="dark"> - No exemplo, sob o seletor
html:has(meta[name="color-scheme"][content="dark"]), variáveis CSS como--color-bge--color-textrecebem valores de modo escuro - Assim, é possível identificar o tema com base no elemento meta real, sem classes nem atributos de dados adicionais
- Ao implementar o seletor do Level 7, é comum adicionar uma classe
Discussões e observações adicionais
-
Observação do CSS Naked Day
- Ao visitar quase todos os sites com os estilos removidos, a ausência de modo escuro chamou atenção, e isso levou à distinção em níveis do modo escuro
- O texto também comenta que, ao construir um site novo do zero e escrever estilos novos, os recursos recentes de CSS tornaram muito fácil embutir os modos claro e escuro
-
Problemas de acessibilidade no Safari
- O texto aponta que, até relativamente pouco tempo atrás, o Safari não fornecia cores de link acessíveis no modo escuro
- Menciona também a experiência anterior de descobrir esse problema em um CSS Naked Day, remover a meta tag e passar a usar apenas o esquema de cores claro
- Depois a meta tag foi adicionada novamente, mas com a consciência de que, para usuários de versões antigas do Safari, isso pode causar queda de acessibilidade
- Também foi constatada a ausência de bordas visíveis em caixas de texto no modo escuro do Safari
- Como apenas os estilos do user agent não garantem acessibilidade completa mesmo com HTML semântico correto, o autor considera manter CSS suficiente também em futuros CSS Naked Days
-
Impressão e a condição
screen and- No exemplo de Bisectional, o uso de
screen and ...é explicado como uma forma de excluir o destino de impressão - Parte-se da premissa de que existe uma stylesheet central independente de tema ou uma stylesheet específica para impressão, e de que separar isso é uma decisão segura, já que o modo escuro na impressora poderia gastar mais tinta
- Em testes reais, mesmo imprimindo com o modo escuro do sistema ativado, a saída foi apenas texto preto em papel branco, sugerindo que os navegadores não aplicam esses estilos de modo escuro à impressão
- Em testes adicionais, no preview de impressão
prefers-color-schemesempre foi reportado como light, algo confirmado no Firefox e no Chromium - O texto fecha com uma observação bem-humorada de que seria uma pena se existisse uma impressora que usasse papel preto e tinta branca
- No exemplo de Bisectional, o uso de
1 comentários
Comentários do Hacker News
userContent.cssdo Firefox