Réaliser un menu responsive avec Flexbox

Le positionnement des éléments à toujours était un vrai problème même s’il y a eu des systèmes de positionnement comme bloc, inline-block, table … Que ce soit les floats ou les inline-block. Il n’est pas rare de rencontrer des problèmes dans ce domaine. Heureusement, il y a eu des avancées et aujourd’hui, avec l’abandon progressif des anciens navigateurs comme Internet Explorer, nous allons pouvoir commencer à aligner nos éléments avec l’aide du module Flexbox. Dans ce tutoriel, je vais vous démontrer comment il est facile de réaliser un menu en quelques lignes seulement.

Étape 1 – La base

Avant de commencer à faire du css, nous allons définir la base de notre menu 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>

Nous allons appliquer un style de base pour notre menu :

.nav ul {
    margin: 0px;
    padding: 0px;
    background: tomato;
    list-style:none;
}

.nav a {
    padding: 1em;
    display: block;
    text-align:center;
    text-decoration: none;
}

Étape 2 – Le menu

Une fois qu’on a initié les bases à nos éléments, On vas pouvoir s’attaquer maintenant à notre menu !

.nav .menu {
    display: flex; /*1*/
    flex-direction : row; /*2*/
    justify-content: center; /*3*/
}
  • 1 – On défini l’affichage en mode flexbox.
  • 2 – Avec flex-direction, on souhaite que les enfants de notre élément courant soit aligné en ligne.
  • 3 – justify-content nous permet d’alligner les enfant à gauche, au centre ou à droite de notre élément courant

flexbox01.JPG

En seulement 3 lignes, vous avez le début d’un menu, si vous avez besoin de l’alligner à droite, il suffit simplement de mettre flex-end à l’attribut justify-content, vous voulez inversé la ligne ? mettre row-reverse à flex-direction. Flexbox est non seulement plus simple mais également très flexible. Et si je vous disais que la version mobile ne prends qu’une ligne?

.nav .menu {
    display: flex; /*1*/
    flex-direction : row; /*2*/
    justify-content: center; /*3*/

    @media(max-width: 450px) {
      flex-flow: column wrap; /*4*/
    }
}
  • 4 – Une fois sur une résolution de type mobile, avec l’aide de flex-flow qui est un raccourcie de flex-direction est de flex-wrap, on affiche les enfants par colonnes et on autorise le retour à la ligne.

flexbox02.JPG

Et voila, bon d’accord, en réalité il y en a 3 mais bon, si on s’arrête là nous avons une première version basique de notre menu responsive mais vous le savez bien, il y aussi des sous-menus et c’est ce que nous allons voir dans la prochaine étape !

See the Pen Menu responsive avec Flexbox – 1 by Damien Flandrin (@dam62500) on CodePen.

Étape 3 – Les sous-menu

Pour réaliser un sous-menu, nous allons créer deux classes, has-children qui s’appliquera à un élément de notre menu qui dispose d’un sous-menu et la 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 -->

Pour mon exemple, j’ai décidé d’ajouter un sous-menu dans un sous-menu ( inception ! ), on sait qu’il n’est pas rare de rencontrer ce genre de cas.

  .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 – On positionne notre élément en relatif dans le but de pouvoir aligner le sous-menu en fonction de son parent.
  • 2 – Si le curseur de la souris est sur un élément contenant un sous-menu, on affiche le sous-menu en mode flexbox.
  • 3 – On définit le comportement par défaut de notre sous-menu, de base il doit être caché, il sera aligné en colonne, on lui ajoute une taille minimale de 100 px ( pas obligatoires mais disons que dans mon exemple, on aurait un sous-menu ridiculement petit ).
  • 4 – On aligne à gauche le texte pour une question d’esthétique.
  • 5 – on aligne le sous sous-menu à la même hauteur que son parent et à sa droite ( right: 0 px; ne fonctionnerait pas dans ce genre de cas).

flexbox03.JPG

Et pour la déclinaison 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;
}

flexbox04.JPG

Privilégier le Javascript vous vos interfactions avec les utilisateurs mobiles et tablettes et je rajouterai également de réaliser un menu en slide si vous avez des sous-menus même si dans mon tutoriel, je n’en ai pas fait un, c’est beaucoup plus ergonomique pour vos visiteurs.

$('.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.

Compatibilité de Flexbox

Flexbox est plutôt bien supporté parmi les navigateurs mais il y a quand même quelques petites choses à connaître afin de bien optimiser son support. à l’heure d’aujourd’hui on peut commencer à envisager d’utiliser Flexbox et il ne fait pas de doute que d’ici quelques années, nous allons voir son utilisation croite grandement, même parmi les frameworks les plus célébres comme Bootstrap ou Foundation.

Internet Explorer Firefox Chrome Safari Android
Support à partir de Internet Explorer 10 avec son préfix -ms-, sans préfix au-delà de 10. Firefox 19 à 21, utiliser son préfix -moz-, sans préfix au-delà de 21 Jusqu’à la version 28 avec -webkit-, sans préfix au-delà de 28 Jusqu’à 10 -webkit-, sans préfix au-delà Avec -webkit- jusqu’à la version 4.3, sans préfix au-delà

Nouveau Tutoriel

Newsletter

Ne manquez jamais les nouveaux conseils, tutoriels et autres.

Pas de spam, jamais. Nous ne partagerons jamais votre adresse électronique et vous pouvez vous désabonner à tout moment.