WordPress isn’t always the friendliest thing in the world to style and the WordPress menus are no different. To get at the WordPress menu CSS takes a couple of hoops to jump through, but I’ll walk you through them now to illustrate how it can be done.

With everything wrapped up in that wp_nav_menu() Template Tag, how do we get our styles and customizations in there to make that navigation look the way we want it?

Changing Menu CSS Styles

Let’s say that we have navigation on our site, displayed like so:

<?php wp_nav_menu(
  array(
    'theme_location' => 'main'
  )
) ?>

The first thing that needs to go is that <div> it’s using to put the unordered list in. We’re writing HTML5 here, we don’t need no stinkin’ <div> . By adding another parameter on the wp_nav_menu() call, we can wrap the navigation in a proper <nav> tag.

<?php wp_nav_menu(
  array(
    'theme_location' => 'main',
    'container' => 'nav'
  )
) ?>

That’s better. You should see that the <div> has now been replaced by a <nav> . We still have a class called menu-primary-container added to it, which should be fine.

Let’s say we’re also using Bootstrap CSS to style this page, so the menu looks a bit weird at the moment. Luckily, we also have a little bit of control over the <ul> classes too, so let’s add the Bootstrap navigation CSS classes to it.

<?php wp_nav_menu(
  array(
    'theme_location' => 'main',
    'container' => 'nav',
    'menu_class' => 'nav nav-pills'
  )
) ?>

Now the <ul> has two new classes, nav and nav-pills , and looks very nice indeed in our theme. We now show the <ul> in a <nav> tag and added extra classes to our <ul> so that we can style it how we choose.

Changing Item CSS Styles

But links on the navigation don’t highlight when we’re on the page for an item! Bootstrap uses the CSS class active to show the current page while WordPress uses current-menu-item . If you’re in control of your CSS, you should honestly just use the WordPress classes. You’ll save a lot of time.

But sometimes, like for me, you just don’t have control over the CSS. Luckily, there is a way to investigate each item’s classes as it’s displayed and modify them, if needed. To do that, we’ll need to head to our functions.php file.

We’re now going to add another function and hook it up to WordPress right before WordPress shows a menu item:

function mytheme_menu_item_classes($classes){
  if( in_array('current-menu-item', $classes) ){
    array_push($classes, 'active');
  }
  return $classes;
}
add_filter('nav_menu_css_class' , 'mytheme_menu_item_classes');

First, I’m defining a function called mytheme_menu_item_classes . Within this function, I’m doing some fancy PHP coding. WordPress is going to give me all the classes that it’s going to add to this <li> item, so I can look at them and see if I need to add in my active class. Since I know WordPress will add the current-menu-item class if this item is the same as the current page, all I need to do is see if that class is in ( in_array() ) the current $classes that WordPress is using and if it is, I’ll add in ( array_push() ) my active class. This might take a bit to wrap your head around, but you can now use this code to add your own specialized classes to any menu item.

Finally, I add my function into the WordPress Hook for building the nav menu CSS classes. Now my function will run on every menu item and add the class active whenever an item already has the class current-menu-item .

You now have all you need to fully style any wp_nav_menu() call in your theme.