How I Clean Up WordPress Menus

WordPress Logo

The great thing about WordPress is that it’s highly customisable and full of lots of inbuilt functionality that allows users of all abilities to create great websites. But like many things the strengths of WordPress are sometimes also its weaknesses.

Take for example the extraneous CSS Classes and ID’s WordPress automatically adds to menus created using the custom menus feature. Sure, they can be useful if you need really specific targeting but I prefer to use cascading styles by targeting the parent class of the menu.

A typical navigation list item might look something like this:

<li id="menu-item-191" class="nav-home menu-item menu-item-type-post_type menu-item-object-page current-menu-item page_item page-item-179 current_page_item menu-item-191"><a href="https://heyjoe.studio/">Home</a></li>

There’s the specific page ID as well as a whole bunch of classes, the first “nav-home” I added within the WordPress custom menu feature. The other classes are all generated by WordPress and I don’t really need the majority of them.

Customising Classes in WordPress Menus

So I started thinking about cleaning up the menus to remove unwanted classes. It was pretty easy to find examples of how to remove all the classes I don’t need but keep the ones I do by adding some code to functions.php.

add_filter( 'nav_menu_css_class', function( $classes ) {
    $allowed = array(
        'menu-item-has-children',
        'current-menu-item'
    );
    $output = array();

    foreach ( $classes as $class )
    {
        if ( in_array( $class, $allowed ) )
            $output[] = $class;
    }

    return $output;
});

This is really useful, only the classes I might actually need are generated, in this case “current-menu-item” and “menu-item-has-children”. The problem though is that I’ve added my own classes to each menu item in the list and they are all different so using this method I’d have to list every class for them to display and remember to update the code in functions if I add new navigation items.

Keep My Own WordPress Custom Menu Class

A bit more digging and I found a useful line of code I could add that would enable me to keep any classes that are prefixed with a certain value. By adding the class “nav-home”, “nav-about”, “nav-blog” etc to each custom menus item I could target the partial value to display the full class.

add_filter( 'nav_menu_css_class', function( $classes ) {
    $allowed = array(
        'menu-item-has-children',
        'current-menu-item'
    );
    $output = array();

    foreach ( $classes as $class )
    {
        if ( in_array( $class, $allowed ) )
            $output[] = $class;

        if ( 0 === strpos( $class, 'nav-' ) )
            $output[] = $class;
    }

    return $output;
});

Job done, all unwanted classes have been removed and only the ones I need, including the ones I’ve added myself, are now displayed.