I'm trying to remove all menu-item classes (except for .current-menu-{item/parent/ancestor} and .menu-item-has-children)

function custom_nav_menu_css_class($classes) {
    $classes = preg_replace('/^((menu|page)[-_\w+]+)+/', '', $classes);
    return $classes;
add_filter('nav_menu_css_class', 'custom_nav_menu_css_class');

This almost does the job, except it removes .menu-item-has-children? Any idea what I should change, to exclude it from being removed?

(P.S. I'd rather not use a custom walker...)

1 Answer 1


You could work with a white-list and replace the regular expression with something more readable:

add_filter( 'nav_menu_css_class', function( $classes ) {

    $allowed = [

    return array_intersect( $classes, $allowed );

That would make it easier to maintain the white-list too.

  • Amazing function!!! There's fifty billion KB of useless classes i'll never target. Gone! Retaining active and has children, perfect! This is how WP should ship, it's so bloated....every update is worse. Commented Dec 12, 2019 at 23:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.