Building a Deeply Nested, Accessible Navigation Menu in Headless WordPress & React

Image with photographs

4 minutes read time.

Introduction

  • The Hook: In my previous post, Headless WordPress with Gatsby and Netlify, we laid down the foundations of a blazing-fast decoupled architecture. But headless development always brings hidden UI challenges. Today, we are tackling the ultimate boss of web layout: The Main Navigation.
  • The Problem: WordPress Theme Unit Tests require supporting an infinite layout of nested submenus. When pairing this with a modern UI library like Mantine (v7), we hit a brick wall. Mantine’s native Menu components strictly prohibit nesting, causing mouse hover events and keyboard focus states to clash, rendering the site completely inaccessible.
  • The Solution: Throwing away restricted UI components and building a 100% custom React state machine utilizing the W3C Disclosure Pattern, enabling infinite nesting and flawless keyboard and mouse UX.

Part 1: The Accessibility Gold Standards (WAI-ARIA)

To understand why standard menus fail, we must look at official standards. A production-ready menu must strictly follow the W3C Web Accessibility Initiative (WAI) guidelines.

According to accessibility standards, an element cannot simultaneously act as a hyperlink to a page AND a trigger button to toggle a dropdown.

  • If pressing Enter takes the user to a new page, screen-reader and keyboard users will never see the submenus underneath it.
  • Our Fix: We detached the link from the parent trigger button. We introduced a screen-reader-safe “Overview” link inside the dropdown so that keyboard users can still navigate to the archive page without losing the submenus.

Crucial Web Standards Specs:

For Further Reading:

Part 2: The Infinite Submenu & Viewport Overflow Problem

WordPress users love hierarchy, and the WordPress core menu editor allows you to create submenus inside submenus indefinitely.

Standard CSS dropdowns typically use left: 100% to spawn a submenu to the right. However, as the user keeps nesting deeper, the menu eventually hits the right edge of the browser window (Viewport Overflow), creating nasty horizontal scrollbars or hiding completely off-screen.

The Logic: Dynamic Depth Direction

Instead of complex and heavy client-side JavaScript element rect measurements, we introduced a recursive React tree pattern using a level property:

  • Level 0 (Root): Opens directly downwards.
  • Level 1+ (Deep Submenus): Detects that it is deep in the tree and intelligently changes its CSS positioning anchors to right: 100% and left: auto, forcing the submenus to cascade safely backwards toward the center of the viewport!

Part 3: The Code (Focus-Based Disclosure Pattern)

Here, you can share the structural snippet of how we engineered the custom wrapper.

Instead of relying on unstable hover components, we wired raw React events (onMouseEnter, onMouseLeave, onFocusCapture, and onBlurCapture).

// A quick snippet explaining the Capture mechanism for your readers
<Box 
    onMouseEnter={openMenu}
    onMouseLeave={closeMenu}
    // The Magic: As long as the keyboard focus stays inside this Box, 
    // the submenu stays open dynamically!
    onFocusCapture={openMenu}
    onBlurCapture={(e) => {
        if (!e.currentTarget.contains(e.relatedTarget)) {
            closeMenu();
        }
    }}
    style={{ position: 'relative' }}
>
   {/* Toggle Button & Submenu Map */}
</Box>

Keyboard UX Breakdown:

  1. Tab: Naturally steps through the menu hierarchy. Dropdowns open automatically as focus enters, providing a frictionless flow.
  2. Shift + Tab: Moves backwards seamlessly up the tree.
  3. Escape: Immediately collapses the current dropdown layer.

Conclusion

Decoupling your site with a Headless CMS doesn’t mean you have to sacrifice user experience or accessibility. By stepping away from restrictive third-party layout wrappers and applying native browser specs with React, we achieved an enterprise-grade menu that satisfies the strict WordPress Theme Unit Tests while respecting every single user—whether they navigate with a high-end mouse, a touch screen, or just a keyboard Tab key.

Check out the implementation live on our demo project, Witty Paws!

Share this article:


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.