2

I'm building a site with a mega menu. Here's what the structure looks like:

<ul>
  <li class="active-grandparent">Grandparent
    <ul>
      <li>Parent</li>
      <li>Parent</li>
      <li>Parent</li>
      <li>Parent
        <ul>
          <li>Child</li>
          <li>Child</li>
          <li>Child</li>
          <li>Child</li>
        </ul>
      </li>
    </ul>
  </li>
  <li>Grandparent</li>
  <li>Grandparent</li>
  <li>Grandparent</li>
</ul>

I'd like to add the class "active-grandparent" to the top level Grandparent <li> if you are on that page or a parent / child page.

WordPress gives each active <li> item a class of current-menu-item, but I need to specifically target the grandparent <li> only so I can add some styles for when it's active.

How is this achieved?

Updated As pointed out in the the comments, I could use current-menu-ancestor. However, this is only being generated on the Grandparent <li> when you're on a parent or child page.

To clarify, if you're on the top level Grandparent page (/grandparent), these are the classes which are being generated within the <li>:

.menu-item
.menu-item-type-post_type
.menu-item-object-page 
.current-menu-item 
.page_item page-item-12 
.current_page_item 
.menu-item-has-children 
.menu-item-203

If you're on a parent (/grandparent/parent) or child page (/grandparent/parent/child), these are the classes which are being generated within the Grandparent <li>:

.menu-item 
.menu-item-type-post_type 
.menu-item-object-page 
.current-page-ancestor 
.current-menu-ancestor 
.current-menu-parent 
.current-page-parent 
.current_page_parent 
.current_page_ancestor 
.menu-item-has-children 
.menu-item-203

If it helps, here are how my menus are generated within the template file:

<nav class="sidebar-navigation">
  <ul>
    <?php
      $menu = array( 'container' => false, 'menu_class' => false, 'items_wrap' => '%3$s' );
      // Left
      wp_nav_menu( array_merge(
        array( 'theme_location'  => 'left' ),
        $menu
      ) );
      // Right
      wp_nav_menu( array_merge(
        array( 'theme_location'  => 'right' ),
        $menu
      ) );
    ?>
  </ul>
</nav>
5
  • It should get the class current-menu-ancestor or similar already. Aug 6, 2018 at 12:43
  • current-menu-ancestor is only being generated on the Grandparent <li> when you're on a parent or child page. I've updated my question.
    – Sam
    Aug 6, 2018 at 13:35
  • will you not achieve the same in this way: .active-grandparent = ul.menu-class > .current_page_item, ul.menu-class > .current-menu-ancestor ?
    – nmr
    Aug 6, 2018 at 13:49
  • I need to apply specific styles to Grandparent '<li>', not the parents or children.
    – Sam
    Aug 6, 2018 at 13:51
  • Yes, > char ensure that this styles will be be applied only to first .current-menu-ancestor or first .current_page_item under ul.menu-class. See here .
    – nmr
    Aug 6, 2018 at 14:06

1 Answer 1

6

Styling the top-level item if it's active or a child is active is possible with pure CSS. Use the child selector, >, from the top:

.sidebar-navigation > ul > .current-menu-item,
.sidebar-navigation > ul > .current-menu-ancestor {}

If you want to add a new class, you can use the nav_menu_css_class filter. One of its parameters is $depth, which you can use to affect only top-level items. To tell if it's child is active you can just check for the existence of the current-menu-item or current-menu-ancestor classes:

function wpse_310629_nav_menu_css_class( $classes, $item, $args, $depth ) {
    if ( $depth === 0 ) {
        if ( 
            in_array( 'current-menu-item', $classes ) || 
            in_array( 'current-menu-ancestor', $classes ) 
        ) {
            $classes[] = 'active-grandparent';
        }
    }

    return $classes;
}
add_filter( 'nav_menu_css_class', 'wpse_310629_nav_menu_css_class', 10, 4 );
1
  • Thank you for both solutions, especially the functions alternative.
    – Sam
    Aug 6, 2018 at 14:31

Your Answer

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

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