Olá amigos, hoje vamos aprender a como se estilizar um checkbox. Utilizaremos apenas HTML e CSS e ao final desse tutorial você vai aprender a fazer isso:

GIF Checkbox

Óbvio que podemos usar algumas bibliotecas JS para estilizar nosso componentes, mas utilizar essas bibliotecas é um trade-off ganhamos em produtividade e perdemos em desempenho, ou seja, escrevemos nosso código mais rápido, porém ele se torna mais lento. Claro que se usarmos uma biblioteca ou outra não vai penalizar o desempenho de nossa aplicação, mas para grandes projetos que dependem de frameworks e bibliotecas, tudo que possamos fazer para melhorar o desempenho é válido. Assim, utilizar apenas HTML e CSS deixa nossa aplicação mais rápida e é bom ter essa skill no nosso cinto de utilidades.

Vamos começar

Para esse tutorial precisamos apenas de 2 arquivos, um html e um css. Veja abaixo o estado inicial deles:

  • Arquivos
styling-checkbox
    |---> index.html
    |---> style.css   
  • HTML
<!DOCTYPE html>
<html>
  <head>
    <title>Checkbox's styles</title>
    <link rel="stylesheet" href="./style.css" />
  </head>
  <body>
    <div class="d-flex first">
      <input type="checkbox" id="checkbox1" />
      <label for="checkbox1">Checkbox 1</label>
    </div>

    <div class="d-flex second">
      <input type="checkbox" id="checkbox2" />
      <label for="checkbox2">Checkbox 2</label>
    </div>

    <div class="d-flex third">
      <input type="checkbox" id="checkbox3" />
      <label for="checkbox3">Checkbox 3</label>
    </div>

    <div class="d-flex fourth">
      <input type="checkbox" id="checkbox4" />
      <label for="checkbox4">Checkbox 4</label>
    </div>

    <div class="d-flex fifth">
      <input type="checkbox" id="checkbox5" />
      <label for="checkbox5">Checkbox 5</label>
    </div>
  </body>
</html>
  • CSS
div.d-flex {
  display: flex;
  max-width: 1024px;
  margin: 0 auto;
}

E este é o estado inicial quando abrimos o index no navegador (pode variar de navegador para navegador, no meu caso, abri no firefox):

Checkbox início

Pontos Importantes:

  • Utilizei as classes first, second, third, fourth e fifth apenas para podermos estilizar checkbox diferentes com conteúdos diferentes (se você não entendeu o que eu quis dizer agora, você vai entender no final do texto).
  • No arquivo HTML perceba que o id do checkbox é o mesmo que o for do label. Isso é extremamente importante, caso eles sejam diferentes, o navegador não vai entender quando estivermos clicando
  • No arquivo CSS inicial, utilizamos os conceitos de display flex para alinhar o texto do label com o checkbox

Caso você ainda não domine ou não conhece o funcionamento do CSS Flexbox, sugiro muito que você leia um pouco sobre o assunto, é uma ferramenta muito poderosa que nos ajuda a posicionar os elementos mais facilmente na página. Você pode conhecer um pouco mais vendo a página do MDN Web Docs - Flexbox.

Estilizando nosso primeiro checkbox

Agora iremos por a mão na massa de verdade. A primeira coisa a ser feita, é desaparacer com o checkbox padrão que vem no navegador, normalmente ele é uma coisa horrivelmente feia. Nós iremos esconder o padrão e criar o nosso próprio.

div.d-flex {
    display: flex;
    max-width: 1024px;
    margin: 0 auto;
}

input[type=checkbox] {
    display: none;
}

Perceba no código acima, que nos queremos apenas que os inputs do tipo checkbox desaparecam, os outros tipos de inputs, por exemplo o text, deve continuar no estilo default. E já podemos ver no navegador que os checkbox se tornaram invisíveis:

Checkbox invisíveis

Antes de iniciar o próximo passo, você deve saber uma coisa, o seletor usado no código abaixo diz que para toda tag p que vem após a tag div, deve-se aplicar a cor de fonte coral no paragrafo, ou seja, lê-se de trás para frente e não obrigatóriamente precisa ser dois elementos distintos, poderia ser dois elementos iguais (dois div's ou dois p's).

div + p {
    color: coral;
}

Para melhor exemplificar:

<div></div>
<p>Primeiro após o DIV</p>
<p>Segundo após o DIV</p>

Apenas na primeira tag p seria aplicada a cor coral, pois ela vem após uma div. Já a segunda tag p, o estilo não é aplicado, pois ela vem após uma tag p e não atende os requisitos do seletor.

Sabendo disso, podemos continuar. Agora iremos estilizar os labels apenas dos checkbox (agora você vai entender porque eu parei para explicar o seletor acima).

Iremos aplicar alguns estilos para dá forma ao checkbox. Iremos dizer estilos como o tamanho e as bordas

div.d-flex {
    display: flex;
    max-width: 1024px;
    margin: 0 auto;
}

input[type=checkbox] {
    display: none;
}

input[type=checkbox] + label:before {
    display: flex;
    justify-content: center;
    align-items: center;

    font-size: 20px;

    border: 1px solid #8C8C8C;
    border-radius: 4px;

    width:  1.5rem;
    height: 1.5rem;

    color: transparent;
    transition: .2s;

    margin-right: 16px;

    background: #FFF;
    cursor: pointer;
}

Você pode ver no navegador que ainda estamos um pouco longe do nosso objetivo, mas chegaremos lá. Antes de avançarmos queria falar algumas coisas do código acima:

  • O display flex é para posicionarmos o ícone dentro do checkbox de forma centralizada. O justify-content centralizar o elemento horizontalmente e o align-items centraliza o elemento verticalmente. Novamente fica a dica: MDN Web Docs - Flexbox.
  • A cor foi colocada como transparente pois queremos apenas que o estado selecionado do checkbox tenha cor (faremos isso daqui há pouco).
  • A transição foi inserida somente para termos uma transição suave entre o estado desmarcado e o estado marcado do checkbox.
  • O cursor pointer foi adicionado para informar ao usuário que o elemento é clicável.

Dito isso, iremos agora tratar do estado marcado

input[type=checkbox]:checked + label:before {
    color: #FFF;
    border: 1px solid #1BA7E4;
    background: #1BA7E4
}

No estado marcado adicionamos um background e mudamos a cor da borda para ficar igual ao do background. Ainda não conseguimos ver nada no navegador, pois o content ainda não foi definido.

Agora podemos ir para o ícone de nosso primeiro checkbox. Utilizarei o seletor .first para selecionar apenas o primeiro e nele adicionarei um content no estado marcado:


.first input[type=checkbox] + label:before {
    content: "\2193";
}

Para quem não entender o \2193 isso é unicode e você pode encontrar a referência de todos os elementos aqui: Unicode.

Agora sim, podemos abrir no navegador e ver algo bonito. Antes de irmos para o segundo checkbox, vamos alinhar o label com a caixa de seleção, novamente usaremos o Flexbox

input[type=checkbox] + label {
    margin-top: 5px;
    cursor: pointer;
    display: flex;
    align-items: center;
}

Feito isso, já temos um layout agradável e podemos finalizar estilizando os outros checkbox

Checkbox primeiro

Para o checkbox 2, 3 e 4, utilizaremos o unicode padrão do CSS, sem muitos segredos e todas as referencias podem ser encontrados no link posto anteriormente.


.second input[type=checkbox] + label:before {
    content: "\2605";
}

.third input[type=checkbox] + label:before {
    content: "\2713";
}

.fourth input[type=checkbox] + label:before {
    content: "\2691";
}

E visualizando o index no navegador:

Checkboxs

Para finalizar (deixamos o melhor para o final), podemos utilizar outras fontes de ícones para estilizarmos o nosso checkbox

Usando Font Awesome

Nesse cenário utilizarei o Font Awesome, uma das fontes de ícones mais usadas na Web. Primeiro começarei importando a fonte via CDN.

<head>
    <title>Checkbox's styles</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css" integrity="sha512-+4zCK9k+qNFUR5X+cKL9EIR+ZOhtIloNl9GIKS57V1MyNsYpYcUrUeQc9vNfzsWfV28IaLL3i96P9sdNyeRssA==" crossorigin="anonymous" />
    <link rel="stylesheet" href="./style.css" />
</head>

Agora podemos fazer o mesmo procedimento que fizemos para os outros checkbox's, só que a agora iremos informar qual fonte iremos usar.

.fifth input[type=checkbox] + label:before {
    font-family: "Font Awesome 5 Free"; 
    font-weight: 900; 
    content: "\f007";
}

No código acima, alteramos a fonte do nosso content e então utilizamos o unicode fornecido pelo Font Awesome. Para ter um conhecimento mais aprofundado de como usar o Font Awesome em pseudo elementos (elementos do tipo :after ou :before), você pode ver por aqui: Font Awesome + Pseudo Elementos. Agora sim, temos nossos checkbox's estilizados.

Checkbox font-awesome

GIF Checkbox

Código completo

Agora chegamos ao fim do tutorial. Vou deixar aqui embaixo o código completo:

HTML

<!DOCTYPE html>
<html>
  <head>
    <title>Checkbox's styles</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.1/css/all.min.css" integrity="sha512-+4zCK9k+qNFUR5X+cKL9EIR+ZOhtIloNl9GIKS57V1MyNsYpYcUrUeQc9vNfzsWfV28IaLL3i96P9sdNyeRssA==" crossorigin="anonymous" />
    <link rel="stylesheet" href="./style.css" />
  </head>
  <body>
    <div class="d-flex first">
      <input type="checkbox" id="checkbox1" />
      <label for="checkbox1">Checkbox 1</label>
    </div>

    <div class="d-flex second">
      <input type="checkbox" id="checkbox2" />
      <label for="checkbox2">Checkbox 2</label>
    </div>

    <div class="d-flex third">
      <input type="checkbox" id="checkbox3" />
      <label for="checkbox3">Checkbox 3</label>
    </div>

    <div class="d-flex fourth">
      <input type="checkbox" id="checkbox4" />
      <label for="checkbox4">Checkbox 4</label>
    </div>

    <div class="d-flex fifth">
      <input type="checkbox" id="checkbox5" />
      <label for="checkbox5">Checkbox 5</label>
    </div>
  </body>
</html>

CSS


div.d-flex {
    display: flex;
    max-width: 1024px;
    margin: 0 auto;
}

input[type=checkbox] {
    display: none;
}

input[type=checkbox] + label {
    margin-top: 5px;
    cursor: pointer;
    display: flex;
    align-items: center;
}

input[type=checkbox] + label:before {
    display: flex;
    justify-content: center;
    align-items: center;

    font-size: 20px;

    border: 1px solid #8C8C8C;
    border-radius: 4px;

    width:  1.5rem;
    height: 1.5rem;

    color: transparent;
    transition: .2s;

    margin-right: 16px;

    background: #FFF;
    cursor: pointer;
}

input[type=checkbox]:checked + label:before {
    color: #FFF;
    border: 1px solid #1BA7E4;
    background: #1BA7E4
}

.first input[type=checkbox] + label:before {
    content: "\2193";
}

.second input[type=checkbox] + label:before {
    content: "\2605";
}

.third input[type=checkbox] + label:before {
    content: "\2713";
}

.fourth input[type=checkbox] + label:before {
    content: "\2691";
}

.fifth input[type=checkbox] + label:before {
    font-family: "Font Awesome 5 Free"; 
    font-weight: 900; 
    content: "\f007";
}

#Fim