Dans ce tutoriel je vous propose d'apprendre à créer le fameux menu responsive (vous savez, la petite icone "hamburger" avec ses 3 petites barres qui apparait sur les mobiles). Pour ce tutoriel nous allons faire un menu qui se révèle par le côté, à la manière des applications mobiles natives.

Le code HTML

Pour préparer notre effet nous allons devoir créer une structure HTML spécifique à notre objectif. Ce code va varier suivant l'effet que vous souhaitez donner.

<div class="site-container">
    <div class="site-pusher">
        <header class="header">
            <a href="#" class="header__icon" id="header__icon"></a>
            <nav class="menu">
                <!-- Notre menu -->
            </nav>
        </header>
        <div class="site-content">
            <div class="container">
                <!-- Le contenu du site -->
            </div>
        </div>
        <div class="site-cache" id="site-cache">
        </div>
    </div>
</div>

Faisons un petit point sur les balises, car à première vue cela fait beaucoup de code HTML pour rien.

  • .site-container, cette div nous permettra de mettre un overflow:hidden; pour éviter les scrollbar latérales lorsque le site sortira du cadre ;
  • .site-pusher, c'est sur cet élément que nous allons appliquer le glissement via un transform: translateX(___px) ;
  • .header, vous le devinez ce sera notre header, en position: fixed sur les bureau et static sur les mobiles ( fixed + mobile = :( ) ;
  • .header__icon, sera notre icône que l'on affichera seulement sur mobile ;
  • .menu, le menu qui va se transformer sur mobile sera simplement en float: left ;
  • .site-content, englobera notre contenu et sera en overflow-y: scroll et position: absolute sur mobile ce qui permettra d'isoler le contenu du reste de la structure.

Le CSS

Le principe de notre menu est relativement simple. Dans le cas d'une grande résolution le .menu sera simplement aligné en float: left dans le header.

En revanche lorsque la résolution devient petite nous allons retravailler la structure de notre site :

@media only screen and (max-width: 750px) {
  .site-pusher, .site-container { height: 100%; }
  .site-container { overflow: hidden; }
  .site-pusher {
    transition-duration: 0.3s;
    transform: translateX(0px); 
  }

  .site-content {
    position: absolute;
    top: 66px; /* La hauteur du header */
    right: 0;
    left: 0;
    bottom: 0;
    padding-top: 0;
    overflow-y: scroll;
    -webkit-overflow-scrolling: touch; /* Inertie sur iOS */
  }

  .header { position: static; }

  /* L'icône hamburger, en utilisant le box-shadow */
  .header__icon {
    position: relative;
    display: block;
    float: right;
    width: 50px;
    height: 66px;
    cursor: pointer; }
    .header__icon:after {
      content: '';
      position: absolute;
      display: block;
      width: 1rem;
      height: 0;
      top: 16px;
      left: 15px;
      box-shadow: 0 10px 0 1px white, 0 16px 0 1px white, 0 22px 0 1px white; }

  /* Le menu collé à gauche est masqué grâce à un transform */
  .menu {
    position: absolute;
    right: 0;
    top: 0;
    bottom: 0;
    overflow-y: scroll;
    -webkit-overflow-scrolling: touch;
    background-color: #2a378b;
    width: 450px;
    transform: translateX(450px); 
  }
    /* Un lien par ligne */
    .menu a {
      display: block;
      height: 40px;
      text-align: center;
      line-height: 40px;
      border-bottom: 1px solid #303f9f; 
    }
}

Un petit peu de JS

Donc là on a notre structure qui fonctionne au redimensionnement, en revanche il n'est pas encore possible d'afficher le menu en cliquant sur notre icône. Nous allons gérer les animations en CSS mais il nous faut écrire un peu de JS pour arriver à détecter le clic sur notre icône.

(function($){

    /* Quand je clique sur l'icône hamburger je rajoute une classe au body */
    $('#header__icon').click(function(e){
        e.preventDefault();
        $('body').toggleClass('with--sidebar');
    });

    /* Je veux pouvoir masquer le menu si on clique sur le cache */
    $('#site-cache').click(function(e){
        $('body').removeClass('with--sidebar');
    })

})(jQuery);

Et encore du CSS

Avec notre petit bout de Javascript on a maintenant une classe sur le body qui nous permet de savoir si oui ou non le menu doit être affiché. Le plus dur est déjà fait, lorsque le body aura la class .with--sidebar, il suffit de bouger .site-pusher en modifiant sa transformation CSS.

  /* Toujours dans le @media */
  .with--sidebar .site-pusher {
    transform: translateX(-450px); 
  }
  /* On met un cache par dessus le site-content pour bloquer le scroll et permettre le retour au site */
  .with--sidebar .site-cache {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(0, 0, 0, 0.6); 
  }

Conclusion et idées

Je vous propose ici un effet particulier qui consiste à faire bouger tous le site pour y afficher le menu mais on peut aller plus loin :

  • permettre l'affichage du menu en utilisant un mouvement de swipe (avec la librairie HammerJS par exemple ;
  • utiliser un effet différent en faisant par exemple apparaitre le menu sous le contenu comme sur certaines applis iOS (il faudra alors sortir header.header du .site-pusher (cf vidéo) ;
  • animer l'icône hamburger en utilisant un SVG plutôt que les box-shadow.

Voila de quoi vous amuser !