Receita de Menu Hambúrguer
Tags: beginners, html, css, javascript
Published: 2023-05-25 12:26:58

####Sumário

> * [A importância dos hambúrgueres](#context)
* [Requisitos e características do hambúrguer que iremos cozinhar](#requirements)
* [Ingredientes](#ingredientes)
* [Mise en place: Preparando o HTML](#html)
* [Ligando o forno: configurando o CSS](#css)
* [Misturando com JS: dando vida ao botão](#js)
* [Exemplo prático](#exemplo)

<span id="context">
### A importância dos hambúrgueres
</span>

A TIC Domicílios é uma pesquisa realizada anualmente desde 2005, com o objetivo de medir a posse, o uso, o acesso e os hábitos da população brasileira em relação às Tecnologias da Informação e Comunicação.

Em 2022, o [resultado da pesquisa](https://cetic.br/pt/noticia/92-milhoes-de-brasileiros-acessam-a-internet-apenas-pelo-telefone-celular-aponta-tic-domicilios-2022/) constatou que 92 milhões de brasileiros acessam a internet **apenas** pelo celular.
Além disso o celular é o meio mais utilizado para acessar a internet (99%  das pessoas da amostra o utilizam).

Esses números nos chamam a atenção para a importância da responsividade.

Um problema comum ao desenvolver sites responsivos é lidar com o tamanho reduzido das telas de celulares.

Na maioria das vezes o menu de navegação, que é um dos elementos mais comuns em sites, possui uma solução em comum que é o uso do chamado "menu hambúrguer".

Existem diversas formas de se fazer um menu hambúrguer (algumas mais simples, outras um pouco mais trabalhosas):
- Com/sem animações;
- Usando uma imagens ou elementos html para criar o visual do botão.
- Usando/não usando JavaScript;
- Usando 1 botão (abrir/fechar) ou 2 botões diferentes (abrir e fechar);

Por ser uma dúvida muito recorrente de iniciantes, veremos a seguir uma introdução de como criar esse componente de uma forma muito simples.

<span id="requirements">
### Requisitos e características do hambúrguer que iremos cozinhar
</span>

1. Nosso menu terá 03 links (Home, Produtos e Contato);
2. Utilizaremos apenas 1 botão, que será responsável pela abertura e fechamento do menu hambúrguer;
3. Ao abrir o menu, o ícone do botão será alterado para um ícone de fechar e ao fechá-lo, irá retornar para o ícone padrão de um menu hambúrguer;
4. Não serão usadas animações.

<span id="ingredientes">
### Ingredientes:
</span>

- HTML;
- CSS;
- Javascript.

*Obs: Se você ainda não sabe JavaScript, não precisa se assustar pois além de ser usado o mínimo possível, ainda será explicado passo-a-passo!*


![mise en place](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lcung2h8hxsl3y7a8qel.gif)

<span id="html">
### *Mise en place*: Preparando o HTML
</span>

Para tornar mais simples a visualização do código, nosso cabeçalho `<header>` irá conter apenas o botão `<button>` responsável por exibir/esconder o menu e o menu de navegação `<nav>` que contém uma lista não ordenada `<ul>` com 03 itens de lista `<li>` que possuem uma âncora/link em cada `<a>`.

* É importante se atentar para o uso de tags que tenham valor semântico, como o `<header>` e o `<nav>`.

```html
<header>
  <button class="menu__button">Abrir</button>
  <nav class="menu__nav">
    <ul>
      <li><a href="#">Home</a></li>
      <li><a href="#">Produtos</a></li>
      <li><a href="#">Contatos</a></li>
    </ul>
  </nav>
</header>
```


![hamburguer na churrasqueira](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w0ccae3l7oik0rpytwi3.gif)

<span id="css">
### Acendendo o fogo: configurando o CSS.
</span>

Adicionaremos alguns estilos aos nossos elementos, apenas para facilitar a visualização. Irei separar a estilização em 2 etapas:
- **[Pré-aquecer](#preaquecer)**: nessa parte será incluído tudo que é opcional, feito apenas para melhor apresentação do layout, portanto serão exibidas sem explicações aprofundadas.
- **[Assar](#assar)**: nessa parte irei incluir passo a passo os temperos que darão sabor ao nosso hambúrguer.

Estilizaremos utilizando seletores de tags, apenas para ficar mais fácil de entender a qual elemento estamos nos referindo.

<span id="preaquecer">
### Pré-aquecer
</span>

```css
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

button {
  padding: 5px;
  background: transparent;
  border: solid 3px tomato;
  border-radius: .5rem;
  font-weight: bold;
  width: 4rem;
  cursor: pointer;
}

button:hover {
  background: #000D;
  color: white;
}

ul {
  display: inline-flex;
  flex-direction: column;
  align-items: stretch;
  gap: 1rem;
  border: solid 2px black;
  border-radius: 5px;
}

li {
  list-style: none;
  padding: .3rem 1rem;
}

li:hover {
  background: #0003;
}

li:hover a{
  text-decoration: underline;
}

a {
  text-decoration: none;
  color: black;
}

```

**Nosso resultado atual**:
{% codepen https://codepen.io/RamosCarlosEduardo/pen/NWOOowd %}


<span id="assar">
### Assar
</span>

As alterações a seguir, afetarão diretamente o comportamento do menú.
A intenção é que a navbar esteja inicialmente escondida ao acessarmos a página através deu um dispositivo que possua uma tela pequena.
Para isso, iremos alterar seu display padrão para `none`:
```css
nav {
  display: none;
}
```

Para fazer com que ele volte a aparecer, iremos criar uma classe modificadora com o nome de `nav-active`.
Quando essa classe estiver presente no elemento, ele será exibido. Quando ela for retirada, o elemento voltará a ter `display: none`. Quem fará o controle de incluir/retirar essa classe do nav será nosso botão.
```css
.nav-active {
  display: block;
}
```


![Montando hambúrguer](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5ka9c9jird2ealiacglb.gif)

<span id="js">
### Misturando com JS: dando vida ao botão
</span>

Para que consigamos alterar as classes do nav ao clicar no botão. Precisaremos encontrar o elemento do `<button>` no DOM e armazená-lo em uma variável.
Faremos isso utilizando o comando [querySelector](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector).

Utilizaremos a classe desse botão `.menu__button` para selecionário e o armazenaremos em uma constante com nome de `botao`.
```js
const botao = document.querySelector('.menu__button')
```

Agora adicionaremos um [escutador de eventos](https://developer.mozilla.org/pt-BR/docs/Web/API/EventTarget/addEventListener) nesse botão, para declararmos uma função que será executada sempre que o botão for clicado.
Esse escutador de eventos recebe dois parâmetros, o evento que será escutado (no nosso caso será o Click), e uma função callback que será executada quando o evento for disparado.
```js
botao.addEventListener('click', funcaoCallback)
```
Agora basta criarmos a função que irá adicionar e removar a classe active conforme cliquemos no botão, para isso utilizaremos o método [classList.toggle](https://developer.mozilla.org/en-US/docs/Web/API/Element/classList). Esse método verifica se o elemento possui uma determinada classe, se ele já tiver a classe ela é removida, se não tiver, ela é adicionada.

```js
function funcaoCallback() {
  const menuNav = document.querySelector('.menu__nav')
  menuNav.classList.toggle('nav-active')
}
```

Agora nosso menu já está funcionando, só iremos ajustar um detalhe.
O botão está exibindo o texto "Abrir". Vamos fazer com que esse texto seja alterado para "Fechar" quando o menu já estiver aberto alterando nossa `funcaoCallback` e incluindo um [operador ternário](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Operators/Conditional_operator):
```js
function funcaoCallback() {
  const menuNav = document.querySelector('.menu__nav')
  menuNav.classList.toggle('nav-active')
  
  button.textContent === "Abrir"
    ? button.textContent = "Fechar"
    : button.textContent = "Abrir"
}
```
Alteramos o texto do botão para tornar mais fácil o exemplo. Mas podemos utilizar a mesma lógica para alterar o background, por exemplo, alternando entre um ícone de abrir e fechar.

{% codepen https://codepen.io/RamosCarlosEduardo/pen/OJBBqPm %}

<span id="exemplo">
#### Exemplo prático
</span>

Para melhor visualização do menu em prática, foram incluídos mais alguns elementos no header, ícones no botão do menu e um media querie para alternar.
{% codepen https://codepen.io/RamosCarlosEduardo/pen/dyggGZK %}