If you’re using links with anchors in your menus, you may notice that they sometimes automatically get the class current-menu-item, which may not what you want to. This is especially true if you have a sub-menu with anchors pointing to an ID on a sub page. This would result in all the anchor links being highlighted as active with the current-menu-item class when the sub page is accessed.

Even though anchors have to be set manually in the navigation menu, WordPress hates custom content, as it seems. Similarly to trying to not displaying a 404 page for a non-existing page and rather redirecting to a similar, existing page, the navigation menu tries to link custom links to existing content. If I have a sub page under /sub-page/ and create a custom link in my menu with this path, it will be automatically detected as associated with this page and thus also get all the menu item classes. And since anchors will be ignored in this detection, also a /sub-page/#anchor will be detected as associated with said page.

In my case, this was not desired, since all sub menu items with an anchor also got the current-menu-item class and thus were highlighted as active from design perspective. Thus, I created a small snippet to check whether the menu item is a custom one and contains an anchor. If so, I remove the current-menu-item class from this menu item, if available. The result is that links with anchors never will have the current-menu-item class.

The code snippet:

/**
 * Remove classes from menu items.
 * 
 * @param	\WP_Post[]	$menu_items Menu items
 * @return	\WP_Post[] Updated menu items
 */
function epiphyt_remove_item_classes( array $menu_items ): array {
	foreach ( $menu_items as $menu_item ) {
		// remove class 'current-menu-item' if menu item is custom and contains an anchor
		if (
			$menu_item->type === 'custom'
			&& isset( $menu_item->url )
			&& \str_contains( $menu_item->url, '#' )
			&& ! empty( $menu_item->classes )
		) {
			$key = \array_search( 'current-menu-item', $menu_item->classes, true );
			
			if ( $key !== false ) {
				unset( $menu_item->classes[ $key ] );
			}
		}
	}
	
	return $menu_items;
}

\add_filter( 'wp_nav_menu_objects', 'epiphyt_remove_item_classes' );
Code language: PHP (php)

Reposts

Leave a Reply

Your email address will not be published. Required fields are marked *

To respond on your own website, enter the URL of your response which should contain a link to this post's permalink URL. Your response will then appear (possibly after moderation) on this page. Want to update or remove your response? Update or delete your post and re-enter your post's URL again. (Learn more about webmentions)