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 unoverflow: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 untransform: translateX(___px)
;.header
, vous le devinez ce sera notre header, enposition: fixed
sur les bureau etstatic
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 enfloat: left
;.site-content
, englobera notre contenu et sera enoverflow-y: scroll
etposition: 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 !