
El posicionamiento de los elementos siempre ha sido un problema real, incluso con sistemas como block, inline-block o table. Ya sea con floats o con inline-block, no es raro toparse con complicaciones en este terreno. Por suerte ha habido avances y hoy, con el abandono progresivo de los navegadores antiguos como Internet Explorer, podemos empezar a alinear nuestros elementos con la ayuda del módulo Flexbox. En este tutorial te voy a demostrar lo fácil que es montar un menú en unas pocas líneas.
Paso 1 – La base
Antes de escribir CSS, vamos a definir la base de nuestro menú en 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 a aplicar un estilo básico al menú:
.nav ul {
margin: 0px;
padding: 0px;
background: tomato;
list-style:none;
}
.nav a {
padding: 1em;
display: block;
text-align:center;
text-decoration: none;
}Paso 2 – El menú
Una vez sentadas las bases de nuestros elementos, ¡ya podemos ponernos con el menú!
.nav .menu {
display: flex; /*1*/
flex-direction : row; /*2*/
justify-content: center; /*3*/
}- 1 – Definimos la visualización en modo flexbox.
- 2 – Con flex-direction indicamos que los hijos del elemento actual se alineen en fila.
- 3 – justify-content permite alinear los hijos a la izquierda, en el centro o a la derecha del elemento actual.
En solo 3 líneas ya tienes el principio de un menú. Si necesitas alinearlo a la derecha, basta con poner flex-end en la propiedad justify-content. ¿Quieres invertir la fila? Pon row-reverse en flex-direction. Flexbox no solo es más sencillo, también es muy flexible. ¿Y si te dijera que la versión móvil ocupa una sola línea?
.nav .menu {
display: flex; /*1*/
flex-direction : row; /*2*/
justify-content: center; /*3*/
@media(max-width: 450px) {
flex-flow: column wrap; /*4*/
}
}- 4 – En una resolución de tipo móvil, con la ayuda de flex-flow, que es un atajo de flex-direction y flex-wrap, mostramos los hijos en columna y permitimos el salto de línea.
Y ya está. Bueno, en realidad son 3, pero si nos quedamos aquí ya tenemos una primera versión básica de nuestro menú responsive. Aunque ya lo sabes: también hay submenús, y eso es justo lo que veremos en el siguiente paso.
See the Pen Menu responsive avec Flexbox – 1 by Damien Flandrin (@dam62500) on CodePen.
Paso 3 – Los submenús
Para montar un submenú vamos a crear dos clases: has-children, que se aplicará a un elemento del menú que tenga un submenú, y la clase 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 -->Para mi ejemplo he decidido meter un submenú dentro de otro submenú (nivel inception), porque no es raro encontrarse con 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 el elemento en relativo para alinear el submenú respecto a su padre.
- 2 – Si el cursor del ratón está sobre un elemento que contiene un submenú, mostramos el submenú en modo flexbox.
- 3 – Definimos el comportamiento por defecto del submenú: de entrada debe estar oculto, se alinea en columna y le damos un tamaño mínimo de 100 px (no es obligatorio, pero en mi ejemplo el submenú quedaría ridículamente pequeño).
- 4 – Alineamos el texto a la izquierda por una cuestión estética.
- 5 – Alineamos el sub-submenú a la misma altura que su padre y a su derecha (right: 0 px; no funcionaría en un caso así).
Y ahora la versión responsive:
.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 las interacciones con los usuarios de móvil y tableta, tira de JavaScript. Y si tienes submenús, monta además un menú deslizante: en este tutorial no lo he hecho, pero resulta mucho más cómodo para tus 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.
Compatibilidad de Flexbox
Flexbox está bastante bien soportado por los navegadores, pero hay algunos detalles que conviene conocer para afinar esa compatibilidad. Hoy ya se puede empezar a plantear su uso, y no cabe duda de que dentro de unos años veremos crecer mucho su presencia, incluso en los frameworks más conocidos como Bootstrap o Foundation.
| Internet Explorer | Firefox | Chrome | Safari | Android |
|---|---|---|---|---|
Compatible a partir de Internet Explorer 10 con el prefijo -ms-, sin prefijo por encima de la 10. | De Firefox 19 a 21, usa el prefijo -moz-, sin prefijo por encima de la 21 | Hasta la versión 28 con -webkit-, sin prefijo por encima de la 28 | Hasta la 10 con -webkit-, sin prefijo por encima | Con -webkit- hasta la versión 4.3, sin prefijo por encima |


