À medida que avançamos em direção a uma experiência do usuário melhor e mais acessível na web a cada dia que passa, o modo escuro se tornou um recurso comum para aplicativos da web. Quando se trata do desenvolvimento do modo escuro, é mais do que apenas adicionar um botão de alternância simples e gerenciar a variável CSS. Aqui, discutiremos a criação de uma experiência de modo escuro completa no aplicativo React.
Aqui está o que cobriremos:
Usando as configurações do sistema Gerenciando temas usando variáveis CSS Implementando a alternância do esquema de cores usando react-toggle Armazenamento modo preferencial do usuário usando use-persisted-state Selecionando uma combinação de cores adequada para um público mais amplo Tratamento de imagens no modo escuro
Você pode encontrar o aplicativo de demonstração e seu código no Github.
Usando as configurações do sistema
Ninguém quer ferir os olhos de um usuário quando ele acessa seu site! É uma prática recomendada definir o tema do aplicativo de acordo com as configurações do dispositivo. Consultas de mídia CSS, geralmente conhecidas pelo uso com design responsivo, também nos ajudam a verificar se há outras características do dispositivo.
Aqui, usaremos o prefer-color-scheme que nos dá a preferência escura, clara ou sem preferência com base no esquema de cores selecionado do dispositivo.
Uniforme em sua forma mais simples, isso por si só pode nos ajudar a adicionar um modo escuro aos aplicativos da web:
@media (prefere-color-scheme: dark) {background-color: # 1F2023 color: #DADADA}
Como qualquer outra consulta de mídia, os estilos neste bloco serão aplicados quando o esquema de cores do dispositivo for definido como escuro. Colocá-lo em alguns estilos de componente ficará assim:
import {styleed} from’@ linaria/react’; const Text=styled.p` margin: 12px; cor: # 1F2023; cor de fundo: #FAFAFA; @media (prefere-color-scheme: dark) {background-color: # 1F2023 color: #DADADA} `;
Isso é bom para começar, mas não se pode continuar adicionando esses estilos em cada componente. Neste caso, variáveis CSS são as resposta.
Gerenciando temas usando variáveis CSS
As variáveis CSS são uma ferramenta que faltou no estilo da web por muito, muito tempo. Agora que estão disponíveis em todos os navegadores, CSS é mais divertido e menos trabalhoso.
As variáveis CSS têm como escopo o (s) elemento (s) em que são declaradas e participam da cascata (ou seja, elementos são valores de substituição para filhos).
Podemos aproveitar as variáveis CSS para definir temas de nosso aplicativo. Aqui está um pequeno snippet para lembrar como as variáveis CSS são declaradas:
body {–color-background: #FAFAFA;–color-foreground: # 1F2023; }
Para usar essas variáveis em nossos componentes, vamos trocar códigos de cores por variáveis:
const Text=styled.p` margin: 12px; color: var (-color-foreground); cor de fundo: var (-cor de fundo); `;
Agora que nossas cores estão definidas através da variável CSS, podemos alterar os valores no topo de nossa árvore HTML (por exemplo,
) e o reflexo pode ser visto em todos os elementos:body {–color-background: #FAFAFA;–color-foreground: # 1F2023; @media (prefere-color-scheme: dark) {–color-background: # 1F2023;–color-foreground: #EFEFEF; }}
Implementando uma alternância de esquema de cores
Neste ponto, temos a solução mais simples que funciona com base nas preferências do dispositivo. Agora temos que escalá-lo para dispositivos que não suportam nativamente o modo escuro.
Nesse caso, temos que tornar mais fácil para os usuários definirem suas preferências para nosso aplicativo da web. Optei por react-toggle para tornar nossa solução melhor em a11y junto com uma boa estética. Isso pode ser feito por meio de um botão simples e useState.
Veja como nosso componente de alternância se parece:
import React, {useState} from”react”; importar Alternar de”react-toggle”; export const DarkModeToggle: React.FC=()=> {const [isDark, setIsDark]=useState
Este componente manterá o modo selecionado do usuário, mas e quanto ao valor padrão? Nossa solução CSS respeitou a preferência do dispositivo. Para obter resultados de consulta de mídia em nosso componente de reação, usaremos o reativo . Nos bastidores, ele usa Window.matchMedia () e renderiza novamente nosso componente quando a saída da consulta é alterada.
Uma versão atualizada do botão se parece com o seguinte:
import React, {useState} from”react”; importar Alternar de”react-toggle”; export const DarkModeToggle: React.FC=()=> {const [isDark, setIsDark]=useState
O gancho useMediaQuery leva uma consulta, um valor inicial e um manipulador onChange que é acionado sempre que a saída da consulta é alterada.
Emulando o modo escuro em navegadores
Agora, nosso componente irá estar em sincronia com as preferências do dispositivo e seu valor será atualizado de acordo. Mas como podemos testar se isso foi feito da maneira certa?
Graças aos navegadores amigáveis ao desenvolvedor, podemos emular as preferências de dispositivo dos inspetores de navegador; aqui está como fica no Firefox:
É hora de conectar a mudança de estado do nosso componente de alternância ao CSS. Isso pode ser feito com várias técnicas diferentes. Aqui, optamos pelo mais simples: adicionar uma classe na tag HTML raiz e deixar as variáveis CSS fazerem o resto.
Para acomodar isso, atualizaremos o CSS de nossa tag body:
corpo {–color-background: #FAFAFA;–color-foreground: # 1F2023; &.dark {–color-background: # 1F2023;–color-foreground: #EFEFEF; }}Aqui está nosso efeito para adicionar e remover classes com base no estado:
… useEffect (()=> {if (isDark) {document.body.classList.add (‘dark’); } else {document.body.classList.remove (‘dark’);}}, [isDark]);…
Armazenando o modo preferido do usuário usando use-persisted-state
Se mantivermos o esquema de cores preferido do usuário no estado do componente, pode se tornar problemático, porque não poderemos obtenha os valores fora deste componente. Além disso, ele desaparecerá assim que nosso aplicativo for montado novamente. Ambos os problemas podem ser resolvidos de maneiras diferentes, incluindo com React Context ou qualquer outra abordagem de gerenciamento de estado.
Uma outra solução é usar o use-persisted-estado . Isso nos ajudará a cumprir todos os requisitos. Ele persiste o estado com localStorage e mantém o estado em sincronia quando o aplicativo é aberto em diferentes guias de um navegador.
Agora podemos mover nosso estado de modo escuro em um gancho personalizado que encapsula toda a lógica relacionada à mídia consulta e estado persistente. Esta é a aparência desse gancho:
import {useEffect, useMemo} from’react’; import {useMediaQuery} de’react-responsive’; import createPersistedState de’use-persisted-state’; const useColorSchemeState=createPersistedState (‘colorScheme’); função de exportação useColorScheme (): {isDark: boolean; setIsDark: (valor: booleano)=> void; } {const systemPrefersDark=useMediaQuery ({query:'(prefere-color-scheme: dark)’,}, undefined,); const [isDark, setIsDark]=useColorSchemeState
O componente do botão de alternância será muito mais simples agora:
/** * * ColorSchemeToggle * */import Toggle from’react-toggle’; import {useColorScheme} de’platform/ColorScheme’; import {DarkToggle} de’./Styled’; const ColorSchemeToggle: React.FC=()=> {const {valor, setValue}=useColorScheme (); return (
Selecionando cores de tema escuro
Enquanto o modo escuro em si pode ser considerado um recurso de acessibilidade , devemos nos concentrar em manter esse recurso acessível para um público mais amplo.
Aproveitamos o botão de reação em nossa demonstração para garantir o botão usado para alterar esquema de cores segue todos os padrões a11y. Outra parte importante é a seleção das cores de fundo e de primeiro plano nos modos claro e escuro. Na minha opinião, colors.review é uma ótima ferramenta para testar a relação de contraste entre as cores; ter uma classificação AAA torna nossos aplicativos mais fáceis de navegar e mais confortáveis de olhar.
Manuseando imagens no modo escuro
Para uma estética melhor, geralmente temos páginas com imagens brilhantes. No modo escuro, imagens claras podem se tornar um desconforto para os usuários.
Várias técnicas podem evitar esses problemas, incluindo o uso de imagens diferentes para ambos os modos e a alteração de cores em imagens SVG. Uma maneira é usar filtros CSS em todos os elementos da imagem; isso ajudará a diminuir o cansaço visual quando imagens brilhantes aparecerem na tela do usuário.
Para habilitar isso, nossos estilos globais serão semelhantes a este:
body {–color-background: #FAFAFA;–color-foreground: # 1F2023;–imagem em tons de cinza: 0;-opacidade de imagem: 100%; &.dark {–color-background: # 1F2023;–color-foreground: #EFEFEF;–imagem em tons de cinza: 50%;–opacidade de imagem: 90%; }} img, vídeo {filtro: escala de cinza (var (-imagem-escala de cinza)) opacidade (var (-imagem-opacidade)); }
Conclusão
A acessibilidade em aplicativos da web hoje não é apenas um utilitário. Em vez disso, é um dos requisitos básicos. O modo escuro a este respeito, quando implementado, deve ser considerado um recurso completo que requer muita atenção, assim como qualquer outro recurso crítico.
Neste artigo, estabelecemos uma maneira de implementar o modo escuro em sua totalidade extensão; deixe-me saber nos comentários se você acha que perdi alguma coisa.