Criando um tema escuro com JS e CSS
Ultimamente tem sido comum que vários sites, principalmente os relacionados a tecnologia, que antes possuíam apenas uma tema padrão, de cores claras, e que agora tem criado a possibilidade do usuário utilizar temas de cores escuras.
O StackOverflow lançou seu tema escuro no começo deste ano, e mais recentemente foi a vez do GitHub fazer o mesmo. Até a Google está testando um tema escuro para o seu buscador nos desktops.
Se você não tem tanta familiaridade com o desenvolvimento web, pode acabar pensando que é muito complexo criar um mecanismo de temas para manter um tema claro e um escuro da mesma forma que esses sites fazem.
Porém isso não é verdade! É possível criar um mecanismo de temas apenas utilizando JavaScript e CSS3 puros, sem nenhum outro framework ou ferramenta, e neste artigo eu vou mostrar como isso pode ser feito!
Variáveis, variáveis por todos os lados
Para começar, primeiro você deve entender exatamente o que vamos utilizar para criar o tema.
Primeiro, da parte de JavaScript, não temos muitos segredos, vamos apenas manipular alguns atributos para alterar o tema, e também iremos salvar a seleção do usuário no navegador, já vamos chegar nisso.
A mágica toda acontece com o CSS3, utilizando de suas variáveis.
As variáveis no CSS foram introduzidas na linguagem e podem ser usadas praticamente desde 2012, porém só a partir de 2015 que elas começaram a ser suportadas com maior abrangência pelos navegadores, e hoje praticamente só não é suportado pelo Internet Explorer (nem a Microsoft dá mais suporte para o IE…).
Como essas variáveis funcionam?
Em um arquivo CSS, as variáveis funcionam com um par de chave/valor, bem parecido como as propriedades dentro da regra de um seletor.
A diferença é que você pode definir qualquer nome para uma variável, e ela deve iniciar com dois traços.
Depois, para utilizar de fato a variável, basta utilizar var()
com o nome que foi definido.
Por exemplo, no código abaixo, é possível ver a utilização das variáveis para guardar valores de cores, tamanhos e medidas, etc. Qualquer valor que pode ser definido a uma propriedade, pode ser armazenada em uma variável, e depois elas podem ser reaproveitadas onde for necessário.
Você pode declarar as variáveis dentro de um seletor :root
ou html
, e assim elas estão disponíveis para serem utilizadas nas em todas as regras que você definir posteriormente.
1 | :root { |
Mesmo sem levar em consideração a questão da criação de temas, o uso de variáveis no seu CSS já pode ser de grande valor. Centralizar em apenas um local os valores de cores e medidas diversas utilizadas deixa o código muito mais organizado e facilita a manutenção.
Agora que você já sabe o que são e como as variáveis do CSS podem ser utilizadas, vamos à criação dos nossos temas!
Come To The Dark Side
Para criação do nosso tema, vamos considerar que temos um site simples, composto de um index.html
para a página, um main.js
para o código JavaScript, e um style.css
para definir o estilo dessa nossa página.
Por exemplo, vamos imaginar que tenhamos essas regras no nosso style.css
:
1 | body { |
A primeira coisa que devemos fazer é pegar cada uma dessas cores que estão definidas entre as diversas regras do arquivo, transformar em variáveis, e adicionar em uma regra genérica para todo a tag html
da página.
Lembrando que você também pode fazer o mesmo com o valor de outras propriedades das regras, com as margens, espaçamentos, etc. Mas como o foco aqui é a criação do tema, vamos fazer isso apenas com as cores
1 | html { |
Só de fazer essa alteração você já deixou seu CSS mais organizado, mantendo a página visualmente sem nenhuma alteração.
Agora o que nós precisamos fazer, é criar uma segunda regra com o conjunto de cores que serão utilizados no tema oposto. No caso, essas cores são do tema claro, então precisamos criar as mesmas variáveis para quando formos utilizar o tema escuro.
E para diferenciar entre os dois conjuntos de variáveis, em vez de manter as regras apenas para o seletor da tag html
, vamos definir também em conjunto uma propriedade data-theme
, que vai receber ou o valor light
quando for o tema claro, ou dark
quando for o tema escuro.
Veremos o uso dessa propriedade mais a frente.
1 | html[data-theme="light"] { |
Agora, no nosso arquivo HTML, precisamos definir qual tema será utilizado por padrão, adicionando a propriedade data-theme
para a tag html
da página, com o valor desejado.
1 | <html lang="en" data-theme="light"></html> |
Só com isso você já vai conseguir ver o seu site alternando entre os dois temas criados, basta alterar o valor da propriedade data-theme
entre dark
e light
e recarregar a página que “magicamente” as cores serão alteradas!
Agora é ligar os pontos
Agora que nós temos as cores todas definidas como variáveis, e também já temos as cores do nossos dois temas, vamos precisar de um pouco de JavaScript para criar uma função que troque o valor do atributo data-theme
dinamicamente, permitindo que o usuário escolha o tema que achar mais agradável.
Na interface do usuário, isso pode ser feito de diversas maneiras: com uma caixa de seleção que liste os temas, um checkbox de ativação do tema, um botão que alterna entre claro e escuro, etc. Mas independente da maneira que for, o que deve ser feito internamente é definir na propriedade data-theme
o valor para o tema desejado.
Por exemplo, podemos criar uma função no JavaScript que, caso o tema atual seja o claro, ele alterne para o escuro, e vice-versa. E podemos vincular essa função no evento de clique de um botão que exista na página.
Toda vez que esse botão for clicado, a função irá obter o valor atual da propriedade data-theme
, e irá trocar para o valor inverso, e as cores serão alteradas.
É importante que apenas um elemento na página possua essa propriedade data-theme
, que usualmente é a tag html
ou a body
1 | let themeToggler = document.getElementById("theme-toggler"); |
Refletindo o tema do navegador
Todos os navegadores modernos, como o Chrome, Firefox e o Edge (o novo Edge, não o antigo) também possuem temas claros e escuros neles próprios, e é possível adicionar na nossa página uma função JavaScript que irá tentar obter essa configuração, e a sua página automaticamente ficará com o mesmo tema do navegador.
Essa função pode ser executada cada vez que a página é carregada, e deve buscar pela configuração prefers-color-scheme
no navegador.
Se essa configuração existir e o valor for dark
, definimos esse mesmo valor no nosso atributo data-theme
.
Agora, se a configuração for qualquer outra, ou se por um acaso o navegador não tiver suporte para ela e ela não existir, definimos nosso tema como light
, que é nosso tema padrão.
1 | let browserTheme = window.matchMedia("(prefers-color-scheme: dark)").matches |
Caso você deseje manter o tema escuro como padrão, é só inverter a verificação.
1 | let browserTheme = window.matchMedia("(prefers-color-scheme: light)").matches |
Salvando a seleção do usuário
Podemos também criar uma forma simples de salvar o tema selecionado pelo usuário, mantendo essa informação no localStorage
do navegador.
Desta forma você pode manter entre as seções do usuário o tema de preferência dele.
Para isso, na função de troca do tema, sempre que você alterar o atributo data-theme
, você pode também salvar o valor nolocalStorage
.
1 | localStorage.setItem("theme", targetTheme); |
Com essa informação salva, você pode fazer a chamada para uma outra função no carregamento da página para verificar se existe esse valor armazenado naquele navegador, e se existir, utilizá-lo. Caso contrário, fica definido o tema padrão.
1 | let savedTheme = localStorage.getItem("theme"); |
É possível até juntar na lógica a verificação tanto do tema salvo pelo usuário, quanto fazer refletir o tema do navegador.
Se existir um tema salvo, utiliza este. Caso contrário, tenta obter o tema configurado no navegador. Se o navegador não suportar, vai ficar definido o tema padrão.
1 | let savedTheme = localStorage.getItem("theme"); |
Não se limite aos temas
Com esse mecanismo é possível criar quantos temas forem necessários, basta criar o conjunto de variáveis com os valores das cores de cada tema, e fazer as funções que atualizem o atributo data-theme
.
E também, é claro, as variáveis no CSS são excelentes para deixar o código mais organizado e centralizar as definições em apenas em um local mesmo que você não queira criar nenhum tema, funcionando muito bem também com frameworks de SPA, como o React e o Angular por exemplo, garantindo que todos os componentes sigam os mesmos padrões.
Caso deseje ver um exemplo de implementação desse mecanismo de temas, você pode consultar este repositório do GitHub: https://github.com/lfrigodesouza/dark-theme-with-css
Também pode ver ele em funcionamento nesta página: https://lfrigodesouza.github.io/dark-theme-with-css/
Compartilhe: Twitter - Facebook - LinkedIn