# Como fazer menu dropdown com CSS puro

> Crie menu dropdown com CSS puro sem JavaScript. Técnica acessível usando :hover e :focus para menus suspensos nativos e responsivos. Aprenda!

URL: https://dpw.dev/css/menu-dropdown-css-puro/  
Publicado em: 2020-05-18  
Categoria: css  
Tags: interface  
Autor: Tárcio Zemel

Existem diversas técnicas para fazer um **menu dropdown**; neste artigo mostramos como fazer um menu dropdown com CSS puro!

[Vídeo no YouTube](https://www.youtube.com/watch?v=RyERAzUuZv8)

É bastante comum, quando o assunto é interfaces, a necessidade de se criar um menu dropdown. Menus dropdown são componentes de UI bastante usados, justamente por serem tão úteis.

Existem os dropdown dos mais simples, aos mais complexos; independentemente de qual seja o caso, alguns princípios básicos podem ser usados para seu desenvolvimento.

Neste tutorial, mostramos **como fazer um dropdown menu com CSS puro** através de técnicas comuns do dia-a-dia, que permitem alcançar o resultado final bem facilmente.

Mostraremos os pontos-chave para conseguir o efeito. Para todos os passos, assista ao vídeo acima; para acessar o código completo, [acesse o código completo no repo do projeto](https://github.com/desenvolvweb/menu-dropdown-pure-css).

## Menu dropdown: o HTML

Semanticamente, é correto afirmar (na maioria dos casos) que um menu dropdown é um submenu aninhado em outro menu.

Algumas observações preliminares:

- Será usado como base o [BFB](/indicacoes/basic-front-boilerplate-bfb/) (códigos de estilos em [Sass](/css/o-basico-de-sass/))
- Convenções de nome com BEM
- Também, Namespaces CSS
- Tema do menu fictício (e divertido)

Se você acompanha nossos tutoriais aqui no blog e no [canal YouTube](https://www.youtube.com/c/dpwoficial), já deve estar acostumado a essas tecnologias/convenções.

Então, a estrutura desse dropdown menu não precisa ser mais complexa que:

```html
<ul class="c-dropdown">
  <li class="c-dropdown__item">
    <a href="#" class="c-dropdown__link">In&iacute;cio</a>
  </li>

  <li class="c-dropdown__item">
    <span class="c-dropdown__item-title">Melhores animes</span>

    <ul class="c-dropdown__submenu">
      <li class="c-dropdown__submenu-item">
        <a href="#" class="c-dropdown__submenu-link">Shingeki no Kyojin</a>
      </li>

      <li class="c-dropdown__submenu-item">
        <a href="#" class="c-dropdown__submenu-link">Bleach</a>
      </li>

      <li class="c-dropdown__submenu-item">
        <a href="#" class="c-dropdown__submenu-link">Saint Seiya</a>
      </li>
    </ul>
  </li>

  <li class="c-dropdown__item">
    <a href="#" class="c-dropdown__link">Contato</a>
  </li>
</ul>
```

Como é possível ver, há um `<ul>` primário, com seus itens; então, o item que contém o dropdown também recebe um `<ul>` aninhado.

Uma marcação semanticamente correta, limpa e simples de ser feita. :)

## Menu dropdown: o CSS

Dentro de uma arquitetura SMACSS usando Sass (como é o caso do BFB), conta-se com a liberdade de separar os arquivos de estilo para um organização mais profissional.

Pelos nomes de classes usados, já é possível notar que, neste exemplo de dropdown, tudo será feito em somente um arquivo de estilo.

Entretanto, se for de sua preferência, `c-dropdown__submenu` poderia muito bem, ao invés de Elemento do Bloco "dropdown", um Elemento à parte.

A estrutura geral do estilo é:

```scss
$component-name: "c-dropdown";

.#{$component-name} {
  display: flex;
  list-style: none;
  margin: 0;
  padding: 0;

  &__item {
    // ...
  }

  &__link {
    // ...
  }

  &__submenu {
    // ...
  }
}
```

Inicialmente, "item" ficaria assim:

```scss
&__item {
  color: var(--color-dpw-primary);
  margin: 0 rem(10);
  position: relative;
}
```

Quer dizer, de cor azul (`--color-dpw-primary` é uma variável já presente no BFB), com pequena margem entre cada item.

Uma observação importante para quem ainda não viu o BFB: `rem()` converte o valor informado para a [unidade de medida CSS](/css/unidades-css-rem-vh-vw-vmin-vmax-ex-ch/) `rem`.

Os links de primeiro nível:

```scss
&__link {
  color: var(--color-dpw-primary);
  text-decoration: none;

  &:hover {
    text-decoration: underline;
  }
}
```

Repetição do mesmo azul (para consistência visual) e efeitinho de sublinhado quando no `:hover`.

### O submenu

Agora, o submenu, em si, inicialmente recebe seus estilos-base:

```scss
&__submenu {
  background-color: var(--color-dpw-primary);
  border-radius: $global-radius;
  left: 50%;
  list-style: none;
  margin: 0;
  opacity: 0.25;
  padding: $global-module-size / 2;
  position: absolute;
  top: calc(100% + 10px);
  transform-origin: top center;
  transform: translateX(-50%) rotateX(-90deg);
  transition: all $transition-duration-fast 125ms ease-in;
  width: rem(200);
}
```

Para quem ainda não conhece o BFB, `$global-module-size` é uma variável Sass que guarda o valor `rem(30)`, o que significa que o `padding` informado é o equivalente a `15px`. `$global-radius` guarda o valor `rem(6)`.

Talvez o que mais chame a atenção seja `transform: translateX(-50%) rotateX(-90deg)`. Nesta técnica de menu dropdown com CSS puro, este é um ponto-chave.

O que se está fazendo é rotacionando o menu somente no eixo X (`rotateX`), parecendo que ele "desapareceu", quando, na verdade, está ali, mas parece invisível devido a sua rotação.

Outro ponto bem interessante é o 3º parâmetro de `transition`, que indica um delay. Ele garante que o dropdown não apareça instantaneamente no hover, mas somente depois de 125ms, para a pessoa não o acionar por acidente.

E como fazer para ele "aparecer"? Um menu dropdown aparece com hover (ou clique) no item ancestral; no caso deste, é com hover, então, é preciso garantir:

```scss
&__item {
  // ...

  &:hover {
    .#{$component-name}__submenu {
      opacity: 1;
      transform: rotateX(0) translateX(-50%);
      transition-timing-function: ease-out;
    }
  }
}
```

Ou seja, quando se der o `:hover` em `c-dropdown__item`, seu elemento interno `c-dropdown__submenu` (perceba a interpolação com o nome do próprio componente) tem a rotação revertida, dando o efeito de "aparecer".

![Como fazer menu dropdown com CSS puro: resultado final do menu](/images/blog/menu-dropdown-css-puro/menu-dropdown-css-funcionando.gif)

_Voilà_! Um menu dropdown com CSS puro, semanticamente correto e bastante simples de se codar.

## Conclusão

Como citado, existem diversas técnicas possível para conseguir fazer um menu dropdown com CSS. Inclusive, vários efeitos de aparecer/desaparecer também podem ser usados.

Este dropdown menu tem a vantagem de ser bem simples de se conseguir: usa marcação HTML simples e nenhuma técnica extraordinário de CSS para funcionar.

O ponto-chave é a rotação no eixo X do submenu e sua "desrotação" no hover do elemento ancestral, o que, convenhamos, também é mais difícil de planejar do que executar. :)

Para todos os passos de desenvolvimento do menu dropdown, assista ao vídeo no começo do artigo; para acessar o código completo, [acesse o código completo no repo do projeto](https://github.com/desenvolvweb/menu-dropdown-pure-css).

E você, tem usado alguma outra técnica para menu dropdown? Gostaria de compartilhar algum projeto que está usando? Coloca aí nos comentários!

---

Fonte: [dpw - desenvolvimento para web](https://dpw.dev/) (pt-BR).
Guia para agentes: https://dpw.dev/llms.txt
Índice completo: https://dpw.dev/sitemap-index.xml
Feed: https://dpw.dev/rss.xml
