• English
CONTACT

Salut à tout-te-s,

Voici un second tutoriel sur la personnalisation du menu mobile Divi.

J'avais déjà expliqué comment améliorer l'apparence du menu déroulant en supprimant ses marges et en modifiant l'apparence du texte.

Aujourd'hui nous irons plus loin en redéfinissant complètement la façon d'afficher le menu mobile lorsqu'on appuie sur l'icône associée (le fameux hamburger). Nous verrons ainsi comment modifier indépendamment hauteur, largeur et animation, ce qui vous permettra de créer votre propre style, par exemple :

  • slide in ou expand sous l'entête, sur le côté ou en pleine largeur,
  • slide in sur le côté en pleine hauteur,
  • plein écran avec animation au choix.

Prérequis : Configuration du menu dans Divi

Ce tutoriel ne s'applique qu'au style de menu par défaut de Divi (à définir dans la personnalisation du thème), à savoir le logo à gauche et le menu à droite.

J'essaierai d'adapter le code CSS suivant pour les menus centré et centré inline dans un prochain épisode.

Vous pouvez maintenant continuer à lire les explications, ou sauter directement aux exemples de menu mobile à copier/coller dans le CSS personnalisé de Divi ou dans la feuille de style de votre thème enfant.

Introduction au menu mobile Divi

Même si un simple copier/coller vous permettra de modifier votre menu mobile sans comprendre, voici une courte introduction à son code source pour les curieux et les développeurs en herbe.

Le menu mobile Divi se compose grossièrement de deux éléments :

  • l'entête, défini par les divs .logo_container et #et-top-navigation, inclus dans le div #main-header ;
  • le menu déroulant, défini par la liste ul#mobile_menu, encapsulée dans le div .mobile_nav, lui même encapsulé dans #et-top-navigation.

Cependant, le squelette du code source est un peu plus complexe car il y a pleins de cas à gérer en fonction des réglages du thème et de la largeur de l'écran (avec le menu desktop).

Mais ce qui nous intéresse aujourd'hui peut se résumer au squelette HTML suivant :

<header id="main-header">
	<div class="container clearfix et_menu_container">
		<div class="logo_container"></div>
		<div id="et-top-navigation">
			<div id="et_mobile_nav_menu">
				<div class="mobile_nav opened">
					<span class="mobile_menu_bar mobile_menu_bar_toggle"></span>
					<ul id="mobile_menu" class="et_mobile_menu"></ul>
				</div>
			</div>
		</div> <!-- #et-top-navigation -->
	</div> <!-- .container -->
</header>

Afin de modifier largeur, hauteur et animation du menu déroulant, nous toucherons principalement à la liste ul#mobile_menu, mais il faudra quand-même modifier quelques éléments supplémentaires pour que tout fonctionne correctement.

Icône de fermeture

Le minimum syndical (quand-même, ET...), on remplace le hamburger par une croix lorsque le menu est ouvert :

@media only screen and (max-width: 980px) {
	.mobile_nav.opened .mobile_menu_bar:before {
		content: "\4d";
	}
}

Suppression des marges

Les marges droite et gauche du menu mobile Divi doivent être supprimées. D'une part pour préserver vos yeux, et d'autre part pour pouvoir afficher proprement le menu en plein écran ou pleine largeur, et obtenir des transitions propres.

On doit donc élargir le conteneur principal et adapter la position du logo et de l'icône hamburger :

@media only screen and (max-width: 980px) {
	#main-header .container.clearfix.et_menu_container {
		width: 100%;
	}
	.logo_container {
		padding-left: 30px;
	}
	#et-top-navigation {
		padding-right: 30px;
	}
}

Positionnement du menu

Le menu peut être affiché sous l'entête, ou démarrer en haut de l'écran (pleine hauteur ou plein écran). Dans le second cas, on supprime le bord supérieur de couleur qui sinon se retrouverait collé en haut de l'écran, et on ajoute un padding vertical pour laisser la place au logo et à l'icône de fermeture du menu. Il faut également positionner le z-index du logo et du bouton de fermeture au-dessus du menu déroulant pour y avoir encore accès.

Un menu slide-in horizontal peut venir de la droite ou de la gauche, donc on fixera sa position d'un côté ou de l'autre, et on positionnera le côté opposé en automatique puisque la largeur du menu peut être variable.

@media only screen and (max-width: 980px) {
	#mobile_menu {
		display: block !important;
		/* Slide-in droite */
		right: 0;
		left: auto;
		/* Slide-in gauche */
		right: 0;
		left: auto;
		/* Expand */
		right: 0;
		left: 0;
		/* Sous l'entête */
		top: 80px;
		/* Plein écran ou pleine hauteur */
		top: 0;
		padding-top: 80px;
		border-top: none;
	}
	/* Pleine hauteur */
	.mobile_menu_bar, #logo {
		z-index: 10000;
	}
}

Largeur du menu

La largeur du menu est de 100% par défaut, mais on peut simplement la modifier avec :

@media only screen and (max-width: 980px) {
	#mobile_menu {
		width: 400px;
	}
}

A noter qu'on pourra si besoin utiliser un media query pour limiter la largeur du menu au-delà d'une certaine taille d'écran, mais la repositionner à 100% en-deça pour éviter un affichage trop serré :

@media only screen and (max-width: 480px) {
	#mobile_menu {
		width: 100%;
	}
}

Hauteur du menu

La hauteur du menu s'adapte par défaut à la longueur de la liste contenant les éléments du menu, ce qui nous va très bien.

Mais on pourra imposer au menu d'occuper au moins la hauteur de l'écran (menu plein écran ou slide in pleine hauteur) :

@media only screen and (max-width: 980px) {
	#mobile_menu {
		min-height: 100vh;
	}
}

ou seulement la hauteur disponible sous l'entête :

@media only screen and (max-width: 980px) {
	#mobile_menu {
		min-height: calc( 100vh - 80px );
	}
}

Animation du menu

Le point le plus délicat dans l'affichage du menu réside dans l'animation CSS qui permet de faire apparaître la liste composant le menu.

Il faut savoir par exemple que si positionner l'opacité à 0 permet bien de masquer le menu déroulant, cela ne supprime pas la liste physiquement, et tous les liens du menu sont encore cliquables ! Même en modifiant la propriété z-index, je n'ai pas réussi à l'éviter. Si vous avez une astuce pour un fade-in simple, je suis preneur...

Ou encore, sur un système iOS, la gestion du "overflow: hidden" sur les éléments body et html est un peu étrange, et un ascenseur horizontal apparaît lorsqu'on veut "pousser" le menu hors de l'écran dans le cas d'un menu slide in.

Donc pour contourner ces deux problèmes, la seule solution simple et globale que j'ai pu trouver (sur le net, j'avoue, pas en moi) est d'utiliser une rotation de la liste dans l'espace, pour la positionner perpendiculairement au plan de l'écran ! Ainsi, elle est physiquement introuvable et elle n'a pas besoin d'être sortie de l'écran.

Par exemple, pour l'animation que j'appelle expand, j'effectue une rotation par rapport à l'axe vertical passant par le centre du menu, ce qui donne l'impression qu'il s'étend du centre vers les bords.

Pour le slide in, la rotation se fait par rapport à l'axe vertical passant par un bord (droit ou gauche), ce qui simule un déplacement latéral.

Pour dérouler à partir du haut, on utiliserait l'axe horizontal passant par le bord supérieur, etc...

Je ne vais pas détailler ici chaque animation, vous pourrez les voir dans les exemples ci-dessous. Vous remarquerez au passage que j'ai réduit le temps de transition à 200ms car je trouve que par défaut l'apparition du menu est vraiment trop lente.

Couleurs du menu

Par défaut, le menu mobile déroulant utilise les mêmes couleurs que l'entête, donc celles définies pour la barre primaire dans la personnalisation du thème.

On peut les personnaliser avec :

@media only screen and (max-width: 980px) {
	#mobile_menu {
		background-color: #fff !important;
	}
	#mobile_menu li a {
		color: #333;
	}
}

Exemple 1 : Menu mobile "expand" pleine largeur qui s'ouvre sous l'entête

Code CSS à ajouter à votre feuille de style (par exemple le fichier style.css de votre thème enfant) ou dans le CSS personnalisé des options Divi.

/* Menu mobile "expand" pleine largeur qui s'ouvre sous l'entête */
@media only screen and (max-width: 980px) {

	.mobile_nav.opened .mobile_menu_bar:before {
		content: "\4d";
	}
	#main-header .container.clearfix.et_menu_container {
		width: 100%;
	}
	.logo_container {
		padding-left: 30px;
	}
	#et-top-navigation {
		padding-right: 30px;
	}
	#mobile_menu {
		display: block !important;
		right: 0;
		left: 0;
		top: 80px;
		min-height: calc( 100vh - 80px );
		transition: all .2s ease-in-out;
		transform-origin: center;
	}
	.mobile_nav.closed #mobile_menu {
		transform: rotateY(90deg);
		opacity: 0;
	}
	.mobile_nav.opened #mobile_menu {
		transform: rotateY(0);
		opacity: 1;
	}

}

Exemple 2 : Menu mobile "slide-in" pleine hauteur qui sort du côté droit

Code CSS à ajouter à votre feuille de style (par exemple le fichier style.css de votre thème enfant) ou dans le CSS personnalisé des options Divi.

/* Menu mobile "slide-in" pleine hauteur qui sort du côté droit */
@media only screen and (max-width: 980px) {

	.mobile_nav.opened .mobile_menu_bar:before {
		content: "\4d";
	}
	#main-header .container.clearfix.et_menu_container {
		width: 100%;
	}
	.logo_container {
		padding-left: 30px;
	}
	#et-top-navigation {
		padding-right: 30px;
	}
	.mobile_menu_bar, #logo {
		z-index: 10000;
	}
	#mobile_menu {
		display: block !important;
		right: 0;
		left: auto;
		top: 0;
		padding-top: 80px;
		min-height: 100vh;
		width: 400px;
		border-top: none;
		transition: all .2s ease-in-out;
		transform-origin: right;
	}
	.mobile_nav.closed #mobile_menu {
		transform: rotateY(90deg);
		opacity: 0;
	}
	.mobile_nav.opened #mobile_menu {
		transform: rotateY(0);
		opacity: 1;
	}

}

@media only screen and (max-width: 480px) {

	#mobile_menu {
		width: 100%;
	}

}

Exemple 3 : Menu mobile "slide-in" plein écran qui vient d'en bas

Code CSS à ajouter à votre feuille de style (par exemple le fichier style.css de votre thème enfant) ou dans le CSS personnalisé des options Divi.

/* Menu mobile "slide-in" plein écran qui vient d'en bas */
@media only screen and (max-width: 980px) {

	.mobile_nav.opened .mobile_menu_bar:before {
		content: "\4d";
	}
	#main-header .container.clearfix.et_menu_container {
		width: 100%;
	}
	.logo_container {
		padding-left: 30px;
	}
	#et-top-navigation {
		padding-right: 30px;
	}
	.mobile_menu_bar, #logo {
		z-index: 10000;
	}
	#mobile_menu {
		display: block !important;
		right: 0;
		left: 0;
		top: 0;
		padding-top: 80px;
		min-height: 100vh;
		border-top: none;
		transition: all .2s ease-in-out;
		transform-origin: bottom;
	}
	.mobile_nav.closed #mobile_menu {
		transform: rotateX(90deg);
		opacity: 0;
	}
	.mobile_nav.opened #mobile_menu {
		transform: rotateX(0);
		opacity: 1;
	}

}

Conclusion

Dans le code source de Divi, l'apparition du menu mobile se fait en javascript : le CSS permettant de gérer son affichage est modifié dynamiquement. Heureusement, nous avons pu directement modifier ce comportement en CSS.

Cependant, une fois de temps, si on clique trop vite, par exemple, quand le menu apparait, il peut y avoir un mouvement vertical du menu, ou un léger délai dans l'affichage. Je pense que selon la longueur de l'animation choisie et le moment où on clique, la transition CSS entre en conflit avec le code javascript de Divi qui s'exécute en parallèle.

Donc pour une animation parfaite dans 100% des cas, il faudrait modifier Divi pour désactiver ce code. Si quelqu'un a une idée propre et simple...

A partir de ces quelques exemples, j'espère que vous saurez innover et créer des menus mobiles toujours plus beaux et plus design !

17 commentaires sur cet article

  1. Excellent tutoriel. Autant Divi dispose d’énormément de paramétrage natifs sur les éléments de son builder autant sur le menu mobile c'est assez faible.
    Merci pour le tuto

    1. Merci. Et oui, Divi est déjà bien à la traine, côté options générales du site, mais alors pour les mobiles...

  2. Bonjour Yan,

    Un grand merci pour votre tuto !
    Je viens enfin de résoudre mon problème grâce à votre article.
    Belle journée à vous,
    Aude

  3. Bonjour,

    Je suis tombé sur votre article en cherchant comment agrandir la taille du hamburger. Une idée ? En tous cas merci pour ce(s) partage(s) de connaissance.

    Aucune réponse à votre demande de solution pour désactiver le code JS dans Divi ?

    Encore merci et bonne journée sur les bords de la Garonne 😉

    1. Bonjour Lionel,

      On peut modifier facilement la taille du hamburger en CSS, par exemple :
      .mobile_menu_bar::before {
      font-size: 64px;
      }

      Et non, rien pour désactiver JS 🙁

      Belle journée à vous !

  4. Merci Yan pour ce tuto qui me sauve la vie! j'étais en train de m'arracher les cheuveux et comme par magie ça marche ! moi qui ne suis pas DEV c'est juste au top ! tout fonctionne !

    Une question, a moins que tu es déjà répondu, y a t'il une possibilité quand tu scroll down que le menu suive ta navigation? dès que je scroll je dois remonter tout en haut pour chercher le menu ce qui est un lourd... j'ai tout regardé mais rien trouvé... une idée ?

    Merci beaucoup pour ton travail !

    1. De rien !
      Par contre tu n'as pas dû chercher au bon endroit car premier résultat chez Gogol pour "divi fixed mobile menu" :
      @media (max-width: 980px) {
      .et_non_fixed_nav.et_transparent_nav #main-header, .et_non_fixed_nav.et_transparent_nav #top-header, .et_fixed_nav #main-header, .et_fixed_nav #top-header {
      position: fixed;
      }
      }
      Peut-être à adapter en fonction du style de menu, mais pour moi ça marche 😉

  5. Bonjour,
    J'aimerais écrire "Menu" juste sous les barres de menu sous mobile. Vous pouvez me donner un coup de main ? Merci ++

    1. Bonjour,
      Oui peut-être, si vous me précisez un peu ce que vous entendez par "les barres de menu mobile".
      Voulez-vous écrire "Menu" sous le bandeau du menu de toutes les pages ?

  6. Bonjour Yan et merci pour ces explications.
    Je souhaite utiliser "Exemple 2 : Menu mobile « slide-in » pleine hauteur qui sort du côté droit" mais il y a une erreur dans les premieres lignes de l'exemple, comme si les acolades n'etaient pas balancees. Ce n'est pas le cas mais je ne trouve pas l'erreur. Pouvez-vous me corriger svp ?
    Merci et bonne annee 2019

    1. Hello,
      Effectivement les guillemets fermants autour du caractère de l'icône du menu avaient sauté à cause d'un plugin, que j'ai désactivé. Tout semble OK désormais.
      Merci pour le retour !

  7. Bonjour !
    Excellent post, Amen ça ma sauver ^^, par contre y aurait-il une astuce pour garder les ss-catégories caché (déroulantes) et non visibles comme actuellement ?
    Merci d'avance !

    1. Hello Sandy,
      Malheureusement le code pour cacher/ouvrir les sous-entrées est un peu plus complexe et nécessite du javascript.
      J'en ai deux ou trois exemples, et j'essaierai d'en faire un tuto prochainement 🙂

  8. Bonjour,

    merci pour le tuto, pas mal,
    mais je préfère une autre solution, bien plus simple, plus efficace

    @media only screen and (max-width: 980px) {
    .mobile_nav.opened .mobile_menu_bar:before { content: "\4d"; }
    #main-header .container.clearfix.et_menu_container { width: 100%; }
    .logo_container { padding-left: 30px; }
    #et-top-navigation { padding-right: 30px; }
    .mobile_menu_bar, #logo { z-index: 10000; }
    #mobile_menu {
    display: block !important;
    right: 0;
    left: auto;
    top: 0;
    padding-top: 80px;
    min-height: 100vh;
    width: 100%;
    border-top: none;
    transition: all .2s ease-in-out;
    transform-origin: right;
    background;
    }
    .mobile_nav.closed #mobile_menu { transform: rotateY(90deg); opacity: 0; }
    .mobile_nav.opened #mobile_menu { transform: rotateY(0); opacity: 1; }
    }
    @media only screen and (max-width: 480px) {
    #mobile_menu { width: 100%; }
    }

    Merci, je trouve bcp de choses magnifiques sur votre site.

    1. Bonjour Mariana,
      S'agit-il d'une erreur de copier-coller ?
      Le code que vous proposez est le même que le mien.
      Je suis preneur d'une solution plus simple si vous avez 😉

Laisser un commentaire

Votre adresse IP ne sera pas collectée.
Vous pouvez renseigner votre prénom ou votre pseudo si vous êtes un humain ;-)