Categorias
Geral

Utilizando Dark Mode em sua aplicações web

Nesse post vamos ver como implementar Dark mode em nossas aplicações web, lançado em sistemas operacionais tanto Mobile quanto para Desktop agora podemos controlar a estilização do nosso conteúdo de acordo com a preferência do usuário. Falando um pouco dessa trajetória no inicio da computação por questões de limitação utilizávamos “dark mode” com os famosos monitores de tela preta como o texto verde.

Com a evolução das telas tivemos uma mudança dos sistemas operacionais para representar elementos reais como documentos e images. Com o passar dos anos a comunidade de desenvolvimento passou a utilizar IDEs para codificação em dark, e agora nos últimos anos Dark Mode passou a ser uma opção para sistema operacionais mobile.

Preferências e vantagens

Particularmente por uma longa exposição durante o dia a diversas telas, no trabalho, celular e em casa. Eu utilizo modo como uma forma de descanso mas estudos realizados pelo time do android mostram que dark mode permite uma economia de até 60% em algumas aplicações, por exemplo, o Youtube app em dark mode.

Mas a web não fica para trás, nas últimas versões dos browsers passaram a reconhecer quando o usuário utiliza o modo, Conseguimos através de media queries monitorar a preferência do usuário.

Media Query CSS

@media (prefers-color-scheme: dark) { ... }

@media (prefers-color-scheme: light) { ... }

@media (prefers-color-scheme: no-preference) { ... }

Com essas três media queries conseguimos captar 3 estados: dark, light, no-preference. Assim conseguimos alterar propriedades quando o usuário utiliza um modo especifico, por exemplo:

body {
  color: #000;
  background-color: #fff;
}

@media (prefers-color-scheme: dark) { 
  body {
     color: #fff;
     background-color: #000;
  }
}

Habilitando Dark mode

No MacOS definimos através de configurações > preferencias gerais:

Alterando para Dark Mode Mac OS

Para iOS vamos em Configurações > Tela e Brilho

Como definir dark mode no iOS

Essa é uma maneira que podemos modificar toda a configuração do sistema operacional. Mas quando estamos desenvolvendo ficar trocando todas as configurações do sistema operacional pode se tornar inconveniente. Nas novas versões do Chrome 79 podemos simular essa mudança como o Chrome DevTools. Para isso vamos no seguinte painel.

Com o DeTools aberto clicamos no menu mais opções(três pontos) e habilitamos a opção renderização(rendering), Lá na propriedade “Emulate CSS media feature prefers-color-scheme” conseguimos simular light mode e dark mode.

Tela do devtools do Chrome

Agora que sabemos como simular e qual media query utilizamos, vamos aplicar o código ao projeto utilizado no curso de PWA. Atualmente o tema principal utilizar um background preto com fontes branca, agora vamos criar uma tema light com as cores invertidas:

Resultado final Light vs Dark mode

Controlando as cores com variáveis CSS

Para isso vamos fazer algumas modificações. Atualmente o projeto utiliza SASS, vou levar em consideração o modo light como o modo padrão e para esse exercício vou utilizar as variáveis para CSS para modifica-las quando usuário muda o modo:

//cores com variáveis CSS
:root {
  --primary-color: #fff;
  --secondary-color: #000;
  --ternary-color: #bae2fd;
  --gray-color: #333;
}

@media (prefers-color-scheme: dark) {
  :root {
    --primary-color: #000;
    --secondary-color: #fff;
  }
}

No código acima á parte de nossa solução, temos as variáveis sendo modificadas quando o usuário muda entre modos, assim não precisamos modificar todos os seletores do nosso CSS apenas as variáveis.

Quando testamos nossa aplicação em Dark Mode deparamos com a seguinte situação:

SVGs e images precisa de ajustes

Para esse caso temos duas correções os icones das redes sociais estão como “embedados” em nosso HTML conseguimos controlar a propriedade fill do nosso SVGs para isso adicionamos o seguinte código:

.social__icon {
    width: 25px;
    height: 25px;
    fill: var(--secondary-color);
}

a:hover .social__icon {
    fill: var(--primary-color);
}

Para a logo principal, por conta de ser uma image preto e branco conseguimos inverter sua cor através de filtros CSS:

@media (prefers-color-scheme: dark) {
  .header__picture {
    filter: invert(1);
  }
}

Assim temos o fix para os dois items, lembrando que no caso da imagem funcionou por que eu utilizo uma image monocromática e temos o seguinte resultado:

Observações

Implementações do dark mode pode ser mais complexa que no exemplo acima, por conta da paleta de cores restritas temos uma simples implementação, caso de uma paleta mais complexa preste atenção nos níveis de contraste.

Em caso mais complexos o ideal é dividir o CSS e carregar o estilo para mode preterido pelo usuário, adicionando as seguintes tags em nosso html:

<link rel="stylesheet" href="/dark.css" media="(prefers-color-scheme: dark)">
<link rel="stylesheet" href="/light.css" media="(prefers-color-scheme: no-preference), (prefers-color-scheme: light)">
<!-- Estilo principal -->
<link rel="stylesheet" href="/style.css">

No caso acima temos um estilo geral style.css e dark.css para os usuários que preferem dark mode e light.css para os usuários sem seleção ou light mode. Assim os usuários em dark mode so carregam o css relacionado.

Para browser antigos

Caso o browser não suporte prefers-color-scheme conseguimos adicionar um fallback em nosso código:

<script>
  // Se `prefers-color-scheme` não for suportado pelo browser, o fall back será light mode.
  if (window.matchMedia('(prefers-color-scheme: dark)').media === 'not all') {
    document.documentElement.style.display = 'none';
    document.head.insertAdjacentHTML(
        'beforeend',
        '<link rel="stylesheet" href="/light.css" onload="document.documentElement.style.display = \'\'">'
    );
  }
</script>

Após a inclusão da media query a validação do stylelint acusou a media query como desconhecida, isso por conta da versão do style lint caso passe o mesmo problema atualize o stylelint para versão 10 ou superior e a validação passará a reconhecer a media query

Falso alert de validação das versões antigas do stylelint

Suporte

Atualmente Novembro de 2019 o suporte para a media query prefers-color-scheme é de 74% dos browser do mercado:

Edge, firefox, chrome, safari, opera, iOS safari suas ultimas versões suportam dark mode.

O código completo você encontra em meu github: https://github.com/fellyph/pwa-tutorial/tree/video/dark_mode_20_final

A base desse tutorial vem do projeto utilizado no curso de PWA que estou rodando no Youtube: https://blog.fellyph.com.br/curso-online-progressive-web-apps/

Qualquer dúvida deixe um comentário e até o próximo post.

Esse post foi baseado no artigo “Hello darkness, my old friend” do @tomayac: https://web.dev/prefers-color-scheme/

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *