Accessible Toggle Buttons for Sub-Menus
Adds a real button with aria-expanded next to every menu item that has a sub-menu in classic menus, so keyboard and screen reader users can open and close sub-menus.
Opens WPIDE on
Code
add_filter( 'walker_nav_menu_start_el', function ( $output, $item, $depth, $args ) {
$classes = is_array( $item->classes ) ? $item->classes : array();
if ( ! in_array( 'menu-item-has-children', $classes, true ) ) {
return $output;
}
$label = sprintf( 'Show sub-menu for %s', wp_strip_all_tags( $item->title ) );
return $output . sprintf(
'<button type="button" class="wpide-submenu-toggle" aria-expanded="false" aria-label="%s"><span aria-hidden="true">▾</span></button>',
esc_attr( $label )
);
}, 10, 4 );
add_action( 'wp_footer', function () {
?>
<style>
.wpide-submenu-toggle{background:none;border:0;padding:4px 8px;cursor:pointer;color:inherit;font:inherit;}
.wpide-submenu-toggle:focus-visible{outline:2px solid currentColor;outline-offset:2px;}
.menu-item-has-children.is-open > .sub-menu{display:block;visibility:visible;opacity:1;left:auto;}
</style>
<script>
document.addEventListener('click', function (event) {
var button = event.target.closest('.wpide-submenu-toggle');
if (!button) { return; }
var item = button.parentElement;
var open = button.getAttribute('aria-expanded') !== 'true';
button.setAttribute('aria-expanded', open ? 'true' : 'false');
item.classList.toggle('is-open', open);
});
</script>
<?php
} );
Notes
Style .wpide-submenu-toggle to match your theme; the script opens sub-menus by adding the is-open class.
How to add this snippet
- Install WPIDE on your WordPress site (it is free) and open Code Snippets.
- Use snippet above adds it from the library in one click. Or copy the code into a new snippet with the same code type.
- It is added inactive: review the code and settings, then switch it on.