Accessible Dropdown Menus for  WordPress

Make your WordPress dropdown menus WCAG 2.0 accessible without a plugin.

Here’s a quick function that you can use to make any dropdown menus accessible in your WordPress theme. This assumes that you’re running a layer of JavaScript to actually make .sub-menu items appear when a top level menu item is hovered or clicked on. It wouldn’t be good to add this without having dropdown menus implemented, but hopefully that’s obvious.

/**
 * WCAG 2.0 Attributes for Dropdown Menus
 *
 * Adjustments to menu attributes tot support WCAG 2.0 recommendations
 * for flyout and dropdown menus.
 *
 * @ref https://www.w3.org/WAI/tutorials/menus/flyout/
 */
function wcag_nav_menu_link_attributes( $atts, $item, $args, $depth ) {

    // Add [aria-haspopup] and [aria-expanded] to menu items that have children
    $item_has_children = in_array( 'menu-item-has-children', $item->classes );
    if ( $item_has_children ) {
        $atts['aria-haspopup'] = "true";
        $atts['aria-expanded'] = "false";
    }

    return $atts;
}
add_filter( 'nav_menu_link_attributes', 'wcag_nav_menu_link_attributes', 10, 4 );

This will add two attributes to top level links in a wp_nav_menu():

  1. aria-haspopup="true" — Tells screen readers that a link inside of a <nav> will trigger a submenu
  2. aria-expanded="false" — Tells screen readers that the submenu triggered by a link is hidden by default

This is the recommended approach for “fly-out (or drop-down) menus” provided by the w3.org, more on fly-out menu accessibility can be read on their site directly.

ARIA Labels for Nav Elements

There is one more thing recommended by the WCAG 2.0 spec for dropdown menus, to add a aria-label attribute to any <nav> element. This can be done inside of your theme’s HTML/PHP, here’s a working example pulled from a client website I manage:

<nav class="primary" role="navigation" aria-label="Main Navigation">
    <?php
    wp_nav_menu( array(
        'theme_location' => 'primary',
        'menu_id' => 'primary-menu',
        'depth' => 2,
    ) );
    ?>
</nav>

Conclusion

Once you’ve implemented both of these adjustments you should be well on your way to having accessibile dropdown menus in WordPress. Accessibility is something that must always be tested and verified though, as every site and system is different. I can’t guarantee that following these two steps will ensure that your site is WCAG 2.0 compliant, it’s up to you to test and verify this yourself.

Meet the Author

Kevin Leary, WordPress Consultant

I'm a freelance web developer and WordPress consultant in Boston, MA with 17 years of experience building websites and applications. View a portfolio of my work or request an estimate for your next project.