Nesse post vamos ver como implementar Dark mode em sua aplicação 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) { ... }
Code language: CSS (css)
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;
}
}
Code language: CSS (css)
Habilitando Dark mode
No MacOS definimos através de configurações > preferencias gerais:
Para iOS vamos em Configurações > Tela e Brilho
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.
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:
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;
}
}
Code language: PHP (php)
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:
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);
}
Code language: CSS (css)
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);
}
}
Code language: CSS (css)
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 em sua aplicação web 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">
Code language: HTML, XML (xml)
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>
Code language: HTML, XML (xml)
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
Suporte
Atualmente Novembro de 2019 o suporte para a media query prefers-color-scheme é de 74% dos browser do mercado:
O código completo de como implementar dark mode em sua aplicação web 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/