WordPress doesn't add parent class to menu items that have submenus. Therefore this is required to extend this:

function add_parent_css( $classes, $item ) {
    global $have_children;
    if( $have_children ) {
        $classes[] = 'parent';
    return $classes;
add_filter( 'nav_menu_css_class', 'add_parent_css', 10, 2 );

class custom_walker extends Walker_Nav_Menu {
  function display_element($element, &$children_elements, $max_depth, $depth=0, $args, &$output){
    $GLOBALS['have_children'] = (isset($children_elements[$element->ID]))? 1:0;
    parent::display_element($element, $children_elements, $max_depth, $depth, $args, $output);

The code will insert parent class to all menu items that have sub-menus and this can be then used in CSS like:

.parent:after { content: ">"; }

I'm wondering though, if there is a way to do that without custom menu walker? Just with filters? The reason I'm asking this is because some plugins like WPML ignore custom menu walkers for menu items and their "language switcher" in the menu doesn't get parent class even if has sub-items. Instead of waiting for WPML to fix that I would prefer to just update the menu in a theme to do it in a simpler way.

  • Do you know which related function WPML uses? wp_list_pages, wp_nav_menu etc. – TheDeadMedic Jun 26 '13 at 11:00
  • They add new items to wp_nav_menu but I would prefer to get rid of theme custom menu walker anyway. I would prefer it to have parent class via filter only. – Paul Jun 26 '13 at 11:01

I'm using the following code to achieve this. Doesn't need any walkers or anything else, just insert this into your functions.php and the items with sub-menu will get "menu-parent-item" added as class.

add_filter( 'wp_nav_menu_objects', 'add_menu_parent_class' );
function add_menu_parent_class( $items ) {
    $parents = array();
    foreach ( $items as $item ) {
        //Check if the item is a parent item
        if ( $item->menu_item_parent && $item->menu_item_parent > 0 ) {
            $parents[] = $item->menu_item_parent;

    foreach ( $items as $item ) {
        if ( in_array( $item->ID, $parents ) ) {
            //Add "menu-parent-item" class to parents
            $item->classes[] = 'menu-parent-item'; 

    return $items;    

I've been using this for a long time. Unfortunately I can't remember where I found it, so can't give credits to the one who came up with it.

  • 2020 this still working for me. Thank you – Nuno Sarmento Dec 14 '20 at 20:09
function wpse_104316_nav_menu_css_class( $classes, $item ) {
    if ( ! empty( $item->current_item_parent ) || ! empty( $item->current_item_ancestor ) ) 
        $classes[] = 'parent';
    return $classes;

add_filter( 'nav_menu_css_class', 'wpse_104316_nav_menu_css_class', 10, 2 );

Update: Seems you can't achieve it with the above approach. But you can however "force" the custom walker by hooking onto wp_nav_menu_args:

function wpse_104316_wp_nav_menu_args( $args ) {
    $args['walker'] = new custom_walker;
    return $args;

add_filter( 'wp_nav_menu_args', 'wpse_104316_wp_nav_menu_args', 100 );

Use this in addition to your current code.

  • It raises an error: FATAL ERROR: CANNOT USE OBJECT OF TYPE STDCLASS AS ARRAY IN ... – Paul Jun 26 '13 at 11:12
  • Sorry, try update. – TheDeadMedic Jun 26 '13 at 11:17
  • Both $item->current_item_parent and $item->current_item_ancestor have false for parent and children menu items when I'm viewing parent menu item so it doesn't add parent class to anything unfortunately. – Paul Jun 26 '13 at 11:24
  • Check revision. – TheDeadMedic Jun 26 '13 at 11:43
  • Thanks! This is a good solution to my issue but I'll go with something that doesn't require custom walker. If I may suggest something for anyone trying to do this: do it with jQuery. You'll save time and you'll maintain the code without custom walker which is usually better. WordPress is likely to update their code with "parent-menu-item" class that is added for items that have children: core.trac.wordpress.org/ticket/20191 Hopefully they will also add "description" support and ability to set custom "data-*" attributes or custom classes for more items than just parent wrapper or LI. – Paul Jun 26 '13 at 13:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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