How to automatically add item label as a class for nav menu items in WordPress

Posted on

Let’s say you have a nav menu in your WordPress site with these items:

  • Home
  • About
  • Blog
  • Shop
  • Contact

In WordPress, it is possible to manually set a class for nav menu items when editing custom menus.

Your custom classes can then be used to uniquely style the nav menu items.

Wouldn’t it be convenient if these classes were automatically generated and added to the menu items based on the menu item labels?

For example,

  • Home – home
  • About – about
  • Blog – blog
  • Shop – shop
  • Contact – contact

This can be easily done, thanks to the nav_menu_css_class filter in WordPress.

Simply add this in your child theme’s functions.php:

add_filter( 'nav_menu_css_class', 'custom_add_item_label_as_class', 10, 3 );
/**
 * Automatically adds `<nav-menu-item-label>` class to nav menu items.
 *
 * @param array  $classes Nav menu item classes.
 * @param object $item Nav menu item data object.
 * @param array  $args Nav menu arguments.
 */
function custom_add_item_label_as_class( $classes, $item, $args ) {

    $classes[] = sanitize_title_with_dashes( $item->title );

    return $classes;

}

If you find these classes too generic and wish to automatically add classes like menu-item-blog, use this instead:

add_filter( 'nav_menu_css_class', 'custom_add_item_label_as_class', 10, 3 );
/**
 * Automatically adds `menu-item-<label>` class to nav menu items.
 *
 * @param array  $classes Nav menu item classes.
 * @param object $item Nav menu item data object.
 * @param array  $args Nav menu arguments.
 */
function custom_add_item_label_as_class( $classes, $item, $args ) {

    if ( 'Home' !== $item->title ) {
        $classes[] = 'menu-item-' . sanitize_title_with_dashes( $item->title );
    }

    return $classes;

}

Note that we are excluding Home menu item since WordPress automatically adds menu-item-home class for the built-in Home Page link.

Sample CSS usage:

li.menu-item-home a:before {
    background-image: url(images/home-icon.png);
}

li.menu-item-blog a:before {
    background-image: url(images/blog-icon.png);
}

li.menu-item-about a:before {
    background-image: url(images/about-icon.png);
}