Add class to active top level (grandparent) menu item
-
05-05-2021 - |
문제
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>
해결책
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 );