I'm using the following inside the wp_nav_menu function to create a select dropdown menu where each menu item is an option in the select dropdown...

'items_wrap' => '<select>%3$s</select>'
'before'     => '<option value="">'
'after'      => '</option>'

How do I add the link value in the 'before' declaration? Is there a better way to go about this? I know about wp_dropdown_pages, but that doesn't work because I want users to be able to control the menu from the "Menus" page.

3 Answers 3


You can't do this with wp_nav_menu, because it outputs list items, and you'll generate invalid markup with your code.

Try using wp_get_nav_menu_items() instead.

A quick solution for a drop down menu with a custom walker:

class Walker_Nav_Menu_Dropdown extends Walker_Nav_Menu{

    // don't output children opening tag (`<ul>`)
    public function start_lvl(&$output, $depth){}

    // don't output children closing tag    
    public function end_lvl(&$output, $depth){}

    public function start_el(&$output, $item, $depth, $args){

      // add spacing to the title based on the current depth
      $item->title = str_repeat("&nbsp;", $depth * 4) . $item->title;

      // call the prototype and replace the <li> tag
      // from the generated markup...
      parent::start_el(&$output, $item, $depth, $args);
      $output = str_replace('<li', '<option', $output);

    // replace closing </li> with the closing option tag
    public function end_el(&$output, $item, $depth){
      $output .= "</option>\n";

In your templates use it like this:

  'theme_location' => 'primary', // your theme location here
  'walker'         => new Walker_Nav_Menu_Dropdown(),
  'items_wrap'     => '<select>%3$s</select>',
  • 1
    Actually, when using the "items_wrap" part, that removes the list items, so the markup is ok. I'll check out the link though. Thanks! Commented Sep 1, 2011 at 21:01
  • yes, but that doesn't handle the nested <UL>s :) Commented Sep 1, 2011 at 21:02
  • It actually does :-) Commented Sep 1, 2011 at 21:09
  • 1
    According to the source it doesn't, unless you're using a custom walker... Commented Sep 1, 2011 at 21:21
  • Does this work or not?
    – chrisjlee
    Commented Dec 13, 2011 at 16:38

I have found that useful:

You can follow any responses to simplify css code dropdovn menu.

  1. Add a class parent for items that have a submenu
  2. add depth class (depth0 , depth1, depth2 ...)

add to function.php your theme

class DD_Wolker_Menu extends Walker_Nav_Menu {
    function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ){
        $GLOBALS['dd_children'] = ( isset($children_elements[$element->ID]) )? 1:0;
        $GLOBALS['dd_depth'] = (int) $depth;
        parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
function  add_parent_css($classes, $item){
     global  $dd_depth, $dd_children;
     $classes[] = 'depth'.$dd_depth;
         $classes[] = 'parent';
    return $classes;

now in header.php

wp_nav_menu( array( 'container_class' => '','container' => '',  'menu' => 'header-menu', 'walker'=> new DD_Wolker_Menu ) );

header-menu replaced by the name of your menu

CSS example code may be the

    margin: 0;
    padding: 0;
#menu-header-menu  ul{


#menu-header-menu> li{
    display: inline;
    margin-left: 1.618em;
#menu-header-menu  li{
    list-style: none;
#menu-header-menu  li a{
    text-decoration: none;
    font-size:  1em;
    font-family:    'Lato',Helvetica,Arial,sans-serif ;
    letter-spacing: 1px;
#menu-header-menu li.parent::after{

#menu-header-menu  .sub-menu {
   display: none;
   position: absolute;
   background-color: #fff;

#menu-header-menu  li:hover>.sub-menu{
    display: inline;
    width: auto;
    height: auto;
    border: solid 1px #BBBBBB;
    z-index: +1;

where #menu-header-menu - id the main UL list (you need to update that as well)


Dropdown Menus plugin does answer the question: wp_nav_menu can't be used to create select menu dropdown, whereas plugin provides nifty dropdown_menu() function that does the job admirably.

Not the answer you're looking for? Browse other questions tagged or ask your own question.