Adding a Mobile Menu in WordPress

Content on mobile screens can get cluttered quickly as multiple menu links are added for site navigation. A responsive mobile menu is great way to clean up the design and make the site navigation available on-demand. The possibilities for the layout and behavior are limitless, so for this site I wanted to keep it as minimalistic as possible to match the rest of the overall design. The method below is lightweight and can be easily modified.

First enqueue a new theme file in the functions.php file like this.

wp_enqueue_script( 'evo-menu-js', get_template_directory_uri() . '/js/mobile-menu.js', array( 'jquery' ), true );

Then create a new file named mobile-menu.js with the JavaScript code below saved to it in the /js directory, inside the theme’s directory.

(function($) {
	$('#toggle').toggle( 
		function() {
			$('#popout').animate({ left: 0 }, 'fast', function() {
				$('#toggle').html('<svg role="img" xmlns="http://www.w3.org/2000/svg" width="40px" height="40px" viewBox="0 0 24 24" stroke="var(--txt-color)" stroke-width="1.8" stroke-linecap="square" stroke-linejoin="miter" fill="none" color="var(--txt-color)" aria-label="close menu"><title>Close Menu</title><path d="M6.34314575 6.34314575L17.6568542 17.6568542M6.34314575 17.6568542L17.6568542 6.34314575"/></svg>');
			});
		}, 
		function() {
			$('#popout').animate({ left: -940 }, 'fast', function() {
				$('#toggle').html('<svg role="img" xmlns="http://www.w3.org/2000/svg" width="40px" height="40px" viewBox="0 0 24 24" stroke="var(--txt-color)" stroke-width="1.8" stroke-linecap="square" stroke-linejoin="miter" fill="none" color="var(--txt-color)" aria-label="menu"><title>Menu</title><path d="M6 7L18 7M6 12L18 12M6 17L18 17"/></svg>');
			});
		}
		);
})(jQuery);

Then update the existing menu navigation in the header.php file like this.

<nav id="menu"> /* <-- the existing nav#menu tag */
	<div id="toggle">
		<svg role="img" xmlns="http://www.w3.org/2000/svg" width="40px" height="40px" viewBox="0 0 24 24" stroke="var(--txt-color)" stroke-width="1.8" stroke-linecap="square" stroke-linejoin="miter" fill="none" color="var(--txt-color)" aria-label="menu"><title>Menu</title><path d="M6 7L18 7M6 12L18 12M6 17L18 17"/></svg>
	</div>
	<div id="popout">
		<?php wp_nav_menu( array( 'theme_location' => 'main-menu' ) ); ?> /* <-- the existing wp_nav_menu php */
	</div>
</nav>

Finally, add the CSS below to the theme’s existing stylesheet.

@media (min-width: 940px) {
	#toggle {
		display: none;
	}
}
@media (max-width: 939px) {
	#popout {
		background: var(--block-color);
		opacity: 0.97;
		z-index: 98;
		position: absolute;
		top: 0;
		left: -940px;
		width: 940px;
		max-width: 100%;
		overflow: hidden;
	}
	#toggle {
		float: right;
		z-index: 99;
		position: absolute;
		top: calc(10vw - 8px);
		right: calc(10vw - 8px);
	}
	#toggle:hover {
		cursor: pointer;
	}
	ul#menu-primary-menu.menu li {
		border-bottom: var(--std-brdr) solid var(--txt-color);
		margin-bottom: var(--std-brdr);
		padding: 10vw;
		width: 100%;
	}
	ul#menu-primary-menu.menu li a {
		text-decoration: none;
		width: 100%;
	}
}

Note that the method above uses inline SVG icons for the toggle buttons, and CSS variables like in this previous post. I’ve set the responsive breakpoint to 940px to match my theme’s layout (this should also include most tablets in portrait-orientation).