
Posicionar elementos sempre foi um verdadeiro problema, mesmo com sistemas como block, inline-block ou table. Seja com floats ou com inline-block, não é raro esbarrar em complicações neste terreno. Felizmente houve avanços e hoje, com o abandono progressivo dos navegadores antigos como o Internet Explorer, podemos começar a alinhar os nossos elementos com a ajuda do módulo Flexbox. Neste tutorial vou mostrar-te como é fácil montar um menu em apenas algumas linhas.
Etapa 1 – A base
Antes de escrever CSS, vamos definir a base do nosso menu em HTML5.
<nav class="nav" role="navigation">
<ul clas="menu">
<li><a href="https://www.damienflandrin.fr/blog/post/#">Accueil</a></li>
<li><a href="https://www.damienflandrin.fr/blog/post/#">Catégories</a></li>
<li><a href="https://www.damienflandrin.fr/blog/post/#">À Propos de Moi</a></li>
<li><a href="https://www.damienflandrin.fr/blog/post/#">Contact</a></li>
</ul>
</nav>Vamos aplicar um estilo de base ao menu:
.nav ul {
margin: 0px;
padding: 0px;
background: tomato;
list-style:none;
}
.nav a {
padding: 1em;
display: block;
text-align:center;
text-decoration: none;
}Etapa 2 – O menu
Com as bases dos elementos assentes, podemos agora atacar o menu!
.nav .menu {
display: flex; /*1*/
flex-direction : row; /*2*/
justify-content: center; /*3*/
}- 1 – Definimos a apresentação em modo flexbox.
- 2 – Com flex-direction indicamos que os filhos do elemento atual se alinhem em linha.
- 3 – justify-content permite alinhar os filhos à esquerda, ao centro ou à direita do elemento atual.
Em apenas 3 linhas já tens o princípio de um menu. Se precisares de o alinhar à direita, basta pôr flex-end na propriedade justify-content. Queres inverter a linha? Põe row-reverse em flex-direction. O Flexbox não é só mais simples, é também muito flexível. E se te dissesse que a versão para telemóvel ocupa uma única linha?
.nav .menu {
display: flex; /*1*/
flex-direction : row; /*2*/
justify-content: center; /*3*/
@media(max-width: 450px) {
flex-flow: column wrap; /*4*/
}
}- 4 – Numa resolução de telemóvel, com a ajuda de flex-flow, que é um atalho de flex-direction e flex-wrap, mostramos os filhos em coluna e permitimos a mudança de linha.
E pronto. Bom, na realidade são 3, mas se ficarmos por aqui já temos uma primeira versão básica do nosso menu responsivo. Só que, como bem sabes, também há submenus, e é isso que vamos ver na etapa seguinte.
See the Pen Menu responsive avec Flexbox – 1 by Damien Flandrin (@dam62500) on CodePen.
Etapa 3 – Os submenus
Para montar um submenu vamos criar duas classes: has-children, que se aplica a um elemento do menu que tenha submenu, e a classe sous-menu.
<!-- notre menu flexbox -->
<nav class="nav" role="navigation">
<ul class="menu">
<li><a href="https://www.damienflandrin.fr/blog/post/#">Accueil</a></li>
<li class="has-children"><a href="https://www.damienflandrin.fr/blog/post/#">Catégories</a>
<!-- sous menu-->
<ul class="sous-menu">
<li><a href="https://www.damienflandrin.fr/blog/post/#">Item 1</a></li>
<li><a href="https://www.damienflandrin.fr/blog/post/#">Item 2</a></li>
<li class="has-children"><a href="https://www.damienflandrin.fr/blog/post/#">Item 3</a>
<!-- un sous menu dans un sous-menu-->
<ul class="sous-menu">
<li><a href="https://www.damienflandrin.fr/blog/post/#">Item 1</a></li>
<li><a href="https://www.damienflandrin.fr/blog/post/#">Item 2</a></li>
<li><a href="https://www.damienflandrin.fr/blog/post/#">Item 3</a></li>
<li><a href="https://www.damienflandrin.fr/blog/post/#">Item 4</a></li>
</ul>
<!-- /un sous menu dans un sous-menu-->
</li>
<li><a href="https://www.damienflandrin.fr/blog/post/#">Item 4</a></li>
</ul>
<!-- /sous menu-->
</li>
<li><a href="https://www.damienflandrin.fr/blog/post/#">À Propos de Moi</a></li>
<li><a href="https://www.damienflandrin.fr/blog/post/#">Contact</a></li>
</ul>
</nav>
<!-- /notre menu flexbox -->No meu exemplo decidi meter um submenu dentro de outro submenu (nível inception), porque não é raro deparar com este tipo de casos.
.has-children { /*1*/
position: relative;
}
.has-children:hover > .sous-menu { /*2*/
display: flex;
}
.sous-menu { /*3*/
display: none;
flex-flow: column wrap;
min-width: 100px;
position: absolute;
background: dodgerblue;
}
.sous-menu a { /*4*/
text-align: left;
color:white;
}
.sous-menu .sous-menu { /*5*/
top: 0px;
left: 100%;
background: #1e76d6;
}- 1 – Posicionamos o elemento em relativo para alinhar o submenu em relação ao pai.
- 2 – Se o cursor do rato estiver sobre um elemento que contém um submenu, mostramos o submenu em modo flexbox.
- 3 – Definimos o comportamento por omissão do submenu: à partida tem de estar escondido, alinha-se em coluna e damos-lhe um tamanho mínimo de 100 px (não é obrigatório, mas no meu exemplo o submenu ficaria ridiculamente pequeno).
- 4 – Alinhamos o texto à esquerda por uma questão estética.
- 5 – Alinhamos o sub-submenu à mesma altura do pai e à sua direita (right: 0 px; não funcionaria num caso destes).
E agora a versão responsiva:
.sous-menu {
display: none;
flex-flow: column wrap;
min-width: 100px;
position: absolute;
background: dodgerblue;
@media(max-width: 450px) {
position: static;
}
}
.sous-menu.is-active {
display: flex!important;
}
.sous-menu a { /*4*/
text-align: left;
@media(max-width: 450px) {
text-align: center;
}
color:white;
}
.sous-menu .sous-menu {
top: 0px;
left: 100%;
background: #1e76d6;
}Para as interações com os utilizadores de telemóvel e tablet, usa JavaScript. E se tiveres submenus, faz antes um menu deslizante: neste tutorial não o fiz, mas é bem mais confortável para os teus visitantes.
$('.sous-menu').click(function(){
if ($(window).width() < 450) {
if($(this).hasClass('is-active'))
$(this).removeClass('is-active');
else
$(this).addClass('is-active');
}
});See the Pen Menu responsive avec Flexbox – 2 by Damien Flandrin (@dam62500) on CodePen.
Compatibilidade do Flexbox
O Flexbox é bastante bem suportado pelos navegadores, mas há alguns detalhes que convém conhecer para afinar esse suporte. Hoje já se pode começar a pensar em usá-lo e não há dúvida de que, dentro de alguns anos, veremos a sua presença crescer muito, mesmo nos frameworks mais conhecidos como o Bootstrap ou a Foundation.
| Internet Explorer | Firefox | Chrome | Safari | Android |
|---|---|---|---|---|
Suportado a partir do Internet Explorer 10 com o prefixo -ms-, sem prefixo acima do 10. | Do Firefox 19 ao 21, usar o prefixo -moz-, sem prefixo acima do 21 | Até à versão 28 com -webkit-, sem prefixo acima do 28 | Até ao 10 com -webkit-, sem prefixo acima | Com -webkit- até à versão 4.3, sem prefixo acima |


