O programador é uma espécie humana que vive a base de café e, geralmente, exerce seus poderes binários com maior frequência pela noite.
Seja pra desenvolver algum software ou para estudar na internet, o programador sempre está online de noite. E o que mais incomoda pra gente é abrir um site que encandeia a vista, faltando cegar o cara.
Pesquisas feitas por mim no instagram @ohmycodebr revelaram o seguinte: 9 em cada 10 devs preferem o tema dark no seu editor de código. E durante a noite esse número tende a aumentar.
Visto isso, vou mostrar como implementar o modo dark no seu site utilizando somente javascript, html e css puros.
O projeto
O site que eu irei usar como exemplo de código talvez seja o mais simples que você já viu na vida. Trata-se de um site que usei para mostrar como alinhar divs usando display flex.
O pulo do gato
O que faz toda a nossa lógica funcionar é o input do tipo checkbox lá no topo da página. Aquele botão "Modo dark" não é um simples botão. Na verdade, esse botão é um link, envelopado por uma tag label, que ativará o input. Veja o código abaixo.
<label for="input-dark-mode">
<a class="button">Modo dark</a>
</label>
<input type="checkbox" id="input-dark-mode">
OBS: A tag a deve, obrigatoriamente, não possuir o atributo href. Pois, não queremos ser redirecionados para uma outra página quando formos trocar de tema.
O atributo for do label faz a mágica acontecer pra gente. Quando clicamos no link, a caixa é selecionada. Veja o funcionamento abaixo:
PS: Todo o código está num Gist, incluindo o CSS.
Hora do JS
Antes de mostrar o código, tenho que explicar como vamos fazer a lógica para a aplicação.
A lógica que devemos fazer é essa: Quando o input do modo dark estiver checado, adicionamos uma prepriedade na tag html. Quando ele não tiver checado, removemos essa propriedade.
document.addEventListener('DOMContentLoaded', () => {
const html = document.querySelector('html')
const inputDarkMode = document.getElementById('input-dark-mode')
inputDarkMode.addEventListener('change', () => {
if(inputDarkMode.checked){
html.setAttribute("dark", "true")
}else{
html.removeAttribute("dark")
}
})
})
Traduzindo o código acima:
Quando todo o site for carregado, eu vou guardar a tag html e o input do modo dark. Depois, fico escutando o input. Quando o valor dele for alterado, ou seja, quando ele for marcado ou desmarcado, executa alguns blocos de instruções.
Que blocos são esses?
Se o input mudou o valor e ele está marcado, eu adicionado o atributo dark com o valor true no meu html. Se o input foi alterado e ele não está mais checado, eu removo o atributo dark da minha tag html.
Só isso já faria funcionar. Porém, toda vez que alguém entrasse no meu site (ou recarregasse), o site iria voltar para a configuração padrão (modo light), pois em nenhum momento salvamos aquele "estado" da página.
Para resolver isso, utilizaremos o localStorage. Muito parecido com cookie, armazena chave e valor. Porém, é utilizado em client-side. Já o cookie é utilizado no server-side.
Além disso, o localStorage não tem data de expiração para os valores armazenados (a menos que o usuário apague o cache do navegador. Aí tudo se perde).
Inserindo o localStorage no nosso código:
document.addEventListener('DOMContentLoaded', () => {
const darkModeStorage = localStorage.getItem('dark-mode')
const html = document.querySelector('html')
const inputDarkMode = document.getElementById('input-dark-mode')
if(darkModeStorage){
html.setAttribute("dark", "true")
}
inputDarkMode.addEventListener('change', () => {
if(inputDarkMode.checked){
html.setAttribute("dark", "true")
localStorage.setItem('dark-mode', true)
}else{
html.removeAttribute("dark")
localStorage.removeItem('dark-mode')
}
})
})
Mudaram poucas linhas...
A primeira linha retorna o valor daquela chave dark-mode se existir navegador, caso contrário retorna nulo.
Depois fazemos uma verificação se existe o darkModeStorage (significa dizer que ele encontrou um valor para a chave dark-mode). Se existir, é porque o usuário em algum momento no passado apertou no botão do modo dark. Então, podemos adicionado a propriedade dark no html.
No momento em que verificamos se o input foi checado, setamos uma variável dark-mode com o valor true no localStorage. Caso oinput tenha sido desmarcado, removemos essa chave, pois, não precisamos mais guardar a informação, já que o usuário não quis mais o dark-mode.
Agora o CSS
Existe um jeito que podemos simular um if no CSS 😏
Tudo que precisamos fazer é verificar se o usuário está no modo dark. Se ele tiver, mudamos algumas cores da nossa aplicação.
Veja o exemplo:
html[dark]{
background-color: black;
}
Se existir a propriedade dark na minha tag html, a cor de fundo será preta.
Se não existir, esse bloco nem é executado. E a cor de fundo fica o padrão (branco).
Você também pode fazer isso para os parágrafos e títulos. A cor padrão deles é preta. Se estiver no modo dark, os parágrafos e títulos serão brancos.
Veja o resultado final:
Conclusão
O modo dark deveria ser considerado a oitava maravilha do mundo. É uma técnica muito bem recebida, principalmente a noite, ou para quem tem problema de visão e não pode ver coisas muito claras. De uma forma ou de outra, o programador deve deixar o usuário escolher qual tema se encaixa melhor com a sua visão.
Esse foi um tutorial bem rápido e direto ao ponto sobre o assunto. Para leitura complementar, indico o tutorial de variáveis com CSS e a série de Grid Layout para montar um projeto mais complexo que este do exemplo.
Todo o código para este exemplo está aqui.
Fique de olho também no instagram do blog para acompanhar as novidades, interagir comigo e receber algumas dicas.