Existem diversas técnicas para fazer um menu dropdown; neste artigo mostramos como fazer um menu dropdown com CSS puro!
É 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.
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 (códigos de estilos em 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, já deve estar acostumado a essas tecnologias/convenções.
Então, a estrutura desse dropdown menu não precisa ser mais complexa que:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<ul class="c-dropdown"> <li class="c-dropdown__item"> <a href="#" class="c-dropdown__link">Iní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 é:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
$component-name: "c-dropdown"; .#{$component-name} { display: flex; list-style: none; margin: 0; padding: 0; &__item { // ... } &__link { // ... } &__submenu { // ... } } |
Inicialmente, “item” ficaria assim:
1 2 3 4 5 |
&__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 rem
.
Os links de primeiro nível:
1 2 3 4 5 6 7 8 |
&__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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
&__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:
1 2 3 4 5 6 7 8 9 10 11 |
&__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”.
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.
E você, tem usado alguma outra técnica para menu dropdown? Gostaria de compartilhar algum projeto que está usando? Coloca aí nos comentários!