Dark mode apenas com HTML, CSS e Javascript
Tags: html, css, javascript, beginners
Published: 2021-08-28 18:08:07

Ao implementar o modo escuro no nosso website melhoramos a experiência do usuário, já que o mesmo ganha a possibilidade de escolher qual é o melhor tema para ele.
Existem diferentes maneiras para implementar o modo escuro em websites, das mais simples as mais complexas, e a abordagem que mostro nesse pequeno tutorial, eu considero como a mais simples e menos trabalhosa possível, onde mostro a implementação usando apenas HTML, CSS e Javascript.

Dois conceitos (chaves) serão usados para implementação do modo escuro, as **Variáveis de CSS** para as cores, e o **localStorage** para guardar o tema atual do usuário.

## Variáveis de CSS

As **variáveis de CSS** funcionam como as variáveis de qualquer outra linguagem, onde atribuímos valores a mesma e podemos modificar posteriormente, para implementação do modo escuro, atribuiremos os valores das nossas cores a **variáveis de CSS**, com isso podemos modifica-las dependendo do contexto.
```css
/*criando uma variável de css */
--bg-grey-light: #f5f5f5;

/*usando a variavel de css */
background-color: var(--bg-grey-light);
```
Uma particularidade das **variáveis de CSS** que a torna uma boa alternativa para implementar o **modo escuro** é que todos os elementos que forem declarados dentro do elemento pai irão  
herda-las, sendo assim nos iremos definir as nossas variáveis diretamente no `body` para que todos os elementos dentro do mesmo possam herda-las.

## localStorage API
Para uma melhor experiência de usuário, iremos usar o localStorage para armazenar o estado atual do usuário, dessa forma quando o usuário voltar a acessar o website, o seu tema preferido será aplicado automaticamente.
```javascript
//armazenando na máquina do usuario o tema
localStorage.setItem('theme', 'dark'); 

//acessado o tema da maquina do usuário
localStorage.getItem('theme'); 
// dark
```
## Estrutura do documento
Sendo um projeto muito pequeno, o nosso documento será constituído por dois botões e dois blocos de texto, os botões terão a função de mudar o tema e atualizar a pagina.
> index.html
```html
 <body>
    <div class="container">
      <h1 class="heading">
        Como fazer o dark mode com HTLM, CSS e Javascript apenas
      </h1>
      <div class="buttons">
        //botão para fazer a troca de estados dark/light
        <button id="toggle" class="button">toggle</button>
        //botão para atualizar a página
        <button id="refresh" class="button">refresh</button>
      </div>
      <div class="text-wrapper">
        <p class="paragraph">
          The United States shall be President of the....
        </p>
      </div>
      <div class="text-wrapper">
        <p class="paragraph">
          Why, there's hardly enough of me left...
        </p>
      </div>
    </div>
    <script src="script.js"></script>
  </body>
```  

## Definindo as cores
Ao definir as cores, já que estamos a lidar com dois contextos diferentes, para cada cor no tema claro deve existir uma variante para o tema escuro, e as cores têm de ser definidas de acordo com as suas responsabilidades, tendo assim cores para texto, cores de fundo…
> Definição das variáveis
```css
/* Definição das cores */
body {
  /* cores de texto */
  --text-white: #ffffff;
  --text-dark: #142136;

  /* cores de fundo */
  --bg-grey-light: #f5f5f5;
  --bg-white: #ffffff;
  --bg-blue-dark: #142136;
  --bg-indigo: #6366f1;

  /*
...
*/
}
```

Após definição das variáveis, iremos criar a classe `.dark`, que conterá a definição das mesmas variáveis, só que com o valor das cores alteradas para o tema escuro, assim, no momento em que pretendermos mudar o contexto para o tema escuro, apenas adicionamos a classe `.dark` ao body através do `javascript` dessa forma as variáveis previamente definidas serão sobrepostas pelas que foram definidas na classe `.dark`.
> Definição das variáveis para o tema escuro
```css
.dark {
  --text-white: #e6e6e6;
  --text-dark: #ffffff;

  --bg-grey-light: #142136;
  --bg-white: #22395d;
  --bg-blue-dark: #142136;
  --bg-indigo: #7577e1;
}
}
```
É importante notar que a variável `--text-dark` que tinha o seu valor: #142136, o mesmo foi alterado para #ffffff no contexto do tema escuro, tendo isso em mente, é só repetir o mesmo processo para todas as outras cores do seu código.

Como ficou o arquivo `.css` final:
> style.css
```css
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
/* Definição das cores */
body {
  /* cores de texto */
  --text-white: #ffffff;
  --text-dark: #142136;

  /* cores de fundo */
  --bg-grey-light: #f5f5f5;
  --bg-white: #ffffff;
  --bg-blue-dark: #142136;
  --bg-indigo: #6366f1;

  font-family: "Inter", sans-serif;
  line-height: 1.7;
  background-color: var(--bg-grey-light);
}
.dark {
  --text-white: #e6e6e6;
  --text-dark: #ffffff;
  --bg-grey-light: #142136;
  --bg-white: #22395d;
  --bg-blue-dark: #142136;
  --bg-indigo: #7577e1;
}
.container {
  max-width: 600px;
  margin: 40px auto;
  display: flex;
  padding: 20px;
  flex-direction: column;
}
.text-wrapper {
  width: 100%;
  padding: 20px;
  background-color: var(--bg-white);
  margin-bottom: 40px;
  border-radius: 10px;
}
.paragraph {
  font-size: 16px;
  color: var(--text-dark);
}
.heading {
  font-size: 40px;
  letter-spacing: 1px;
  font-weight: 900;
  margin-bottom: 40px;
  color: var(--text-dark);
}
.buttons {
  width: 100%;
  display: flex;
  justify-content: space-between;
  margin-bottom: 40px;
}
.button {
  width: 200px;
  padding: 5px;
  height: 40px;
  border: none;
  border-radius: 10px;
  font-family: inherit;
  cursor: pointer;
  background-color: var(--bg-indigo);
  color: var(--text-white);
  font-size: 16px;
  font-weight: 400;
  text-transform: capitalize;
}
```
Como pode se ver no código, não foi usada nenhuma cor directamente, mas sim as variáveis previamente definidas.

## Alterando o tema
Para o processo de alteração do tema, usaremos o javascript, e o script primeiro verificará no localStorage se o tema previamente armazenado é escuro e o aplicará ao `body` assim que o mesmo for carregado.
Para o botão de alterar tema, criamos um `eventListener` para quando o mesmo for clicado, remover ou adicionar a classe `.dark` e também alterar o tema armazenado no localstorage dependendo do contexto.
> script.js
```javascript
const toggle = document.getElementById("toggle");
const refresh = document.getElementById("refresh");
const theme = window.localStorage.getItem("theme");

/* verifica se o tema armazenado no localStorage é escuro
se sim aplica o tema escuro ao body */
if (theme === "dark") document.body.classList.add("dark");

// event listener para quando o botão de alterar o tema for clicado
toggle.addEventListener("click", () => {
  document.body.classList.toggle("dark");
  if (theme === "dark") {
    window.localStorage.setItem("theme", "light");
  } else window.localStorage.setItem("theme", "dark");
});

refresh.addEventListener("click", () => {
  window.location.reload();
});
```

Demo: [dark-mode.kelven.dev](https://dark-mode.kelven.dev)
Código fonte: [Repósitorio do Github](https://github.com/Rubalaine/howto-dark-mode)

Muito Obrigado por ler até aqui, espero que o meu texto de alguma forma tenha te ajudado.
Esse é o segundo artigo/blog post que eu escrevo, sinta-se livre pra dar a sua opinião sobre o mesmo, que assim me ajuda a melhorar.
Dê uma olhada no meu [Portfólio](https://kelven.dev) tenho alguns projectos interessantes por lá.