Making select menus with wp_nav_menu()

This post will outline the method for creating a select menu using wp_nav_menu. What this means is that you can have a select menu (sometimes called a dropdown menu) that is built automatically by wordpress and doesn’t require any additional maintenace (assuming you’re already maintaining your default wordpress menu). This type of menu is optimal on mobile sites because it takes up very little room while also leveraging the native UI components on the users mobile operating system. These native UI components are typically touch friendly and extremely familiar to users, lending to your mobile site feeling more polished and complete rather than a feature stripped afterthought. Below is an image of how a select menu appears on iOS and Android;

Select menu on iOS (5.0) and Android (4.0)

So now that you see how it will look, we can dive right into making it. When designing a menu like this the first consideration is how are we going to make it, with javascript or php? I opted for php because it will still work when javascript is turned off (which admittedly isn’t a big concern when we’re talking mobile browsers) and because mobile browsers render pages slow enough without us drastically re-arranging elements during page load. So with that we’ll dive right into the process of creating the menu.

Creating a custom walker

The first thing we’re going to do is create a custom walker class that we will pass to wp_nav_menu(). I’m going to gloss over the details of the walker class for now, if you want the details of exactly what’s being changed you can read about them in this follow up post. For now, you can just copy and paste the following code (link to code) directly into you functions.php file.

Calling the menu

The custom walker discussed earlier takes care of the menu’s output, but we still need to specify $items_wrap to get it surrounded by the correct SELECT tags instead of UL tags. Our code for calling the menu will look like this;

We’re basically calling wp_nav_menu the way we would call it any other time. The only difference is that were using items_wrap to tell it to surround the items with a select tag then setting ‘walker’ to the custom walker class we created above.

Handling the menu

We will handle the menu using both the form’s default action and javascript. While some might want to rely completely on javascript (and the select elements onchange event) this will likely pose problems. Beyond concerns over users with JavaScript disabled (which is extremely rare on mobile browsers) there are issues on iOS where the onchange event is not correctly triggered. Relying on the onchange event will likely make the menu unusable for iOS users. Luckily, the iOS select menu widget automatically triggers the form’s submit action so the inability to use the onchange event doesn’t mean your users are forced to click the submit button after making their selection. In fact, the menu will be triggered correctly without even having a submit button, as long as you specify the form’s action the list picker will execute it. We will include a submit button anyway and hide it with JavaScript. Here is the form code we will use;


As you can see the form triggers a php script in the template directory called nav.php. This is a simple php script that simply changes the page based on the value element. This is what the script looks like;


Handling the menu – javascript

The last thing we’re going to do is add some javscript to trigger the page navigation without needing to hit the submit button. We’ll also use the javascript to hide the submit button all together. I used jQuery because I was already using it in the theme, if the only javascript on your page is the navigation code you should probably avoid the overhead of jQuery. This code simply initiates navigation when the select menu is changed and also hides it’s submit button;

$('#mobile-menu select').change(function(e){
   window.location = $(this).val()
$('#mobile-menu .mob-sub').hide();


And with that we’re done. You will now have a fully functional navigation menu enclosed in a SELECT menu. If you want to dive in deeper and find ways to further customize, read this post which goes into detail about the changes made to the walker class.