Blog

How To Move The Custom Menu Item Classes To The Anchor Element

A common need of WordPress developers is adding custom classes to menu items. Using a custom class allows menu items to be styled differently, perhaps more like a button which is becoming more and more common.

An example of a website I’ve built with a nav item item styled like a button

WordPress does offer custom classes for menu items. If you can’t see a field for adding a CSS Class then you may need to enable it in your screen settings. Adding your classes to this field will add those classes to the menu item’s <li> element.

However sometimes these classes should be applied to the anchor tag rather than the list element. This is particuarly important when using a front-end framework such as Bootstrap, or icon fonts such as Font Awesome.

A lot of the solutions out there suggest using a custom walker. While custom walkers are extremely powerful, they’re usually overkill for this sort of thing. We only want to add and remove some classes and WordPress already provides the filters we need to do this. I’ve also run into issues with plugins that don’t work as they expect the menus to be running the same filters that core does, which is something often overlooked when building a custom walker.

Simply paste the below snippet into your theme’s functions.php file and it will add your custom menu item classes to the anchor tag instead of the list item element.

<?php
add_filter( 'nav_menu_link_attributes','cameronjonesweb_move_custom_menu_item_class_to_anchor_element', 10, 4 );
add_filter( 'nav_menu_css_class', 'cameronjonesweb_remove_custom_menu_item_class_from_li_element', 10, 4 );
/**
* Get the custom item menu classes and add them to the anchor element
*
* @link https://cameronjonesweb.com.au/blog/how-to-move-the-custom-menu-item-classes-to-the-anchor-element/
* @param array $atts The HTML attributes applied to the menu item's `<a>` element, empty strings are ignored.
* @param WP_Post $item The current menu item.
* @param stdClass $args An object of wp_nav_menu() arguments.
* @param int $depth Depth of menu item. Used for padding.
* @return array
*/
function cameronjonesweb_move_custom_menu_item_class_to_anchor_element( $atts, $item, $args, $depth ) {
$custom_classes = get_post_meta( $item->ID, '_menu_item_classes', true );
if ( ! empty( $custom_classes ) ) {
$atts['class'] = empty( $atts['class'] ) ? '' : $atts['class'];
$atts['class'] .= implode( ' ', $custom_classes );
}
return $atts;
}
/**
* Remove the custom classes from the list element
*
* @link https://cameronjonesweb.com.au/blog/how-to-move-the-custom-menu-item-classes-to-the-anchor-element/
* @param array $classes The CSS classes that are applied to the menu item's `<li>` element.
* @param WP_Post $item The current menu item.
* @param stdClass $args An object of wp_nav_menu() arguments.
* @param int $depth Depth of menu item. Used for padding.
* @return array
*/
function cameronjonesweb_remove_custom_menu_item_class_from_li_element( $classes, $item, $args, $depth ) {
$custom_classes = get_post_meta( $item->ID, '_menu_item_classes', true );
$classes = array_diff( $classes, $custom_classes );
return $classes;
}
view raw functions.php hosted with ❤ by GitHub

Did you find this post useful?

YesNo