Responsive & Mobile Navigation: How It Works

WP Rig 3.1+ replaced the old default menu with a purpose-built responsive navigation system: a reworked header, a mobile hamburger experience that works identically in classic PHP menus and the core Navigation block, viewport-aware submenu collision handling, and dedicated test coverage. This post explains how it fits together and how to work on it safely.

One system, two modes: classic & Navigation block

The navigation scripts handle both worlds through one architecture:

  • Classic menus (.nav--toggle-sub markup) get delegated toggling, keyboard traversal, and current-item states (.current-menu-item, .current-menu-ancestor).
  • Core Navigation block gets the same behavior via delegated handling of the wp-block-navigation responsive container — including capture-phase submenu toggling for FSE markup.
  • A styled baseline in _blocks-based.css makes the Navigation block’s default state look like real navigation (see Theme Paradigms).

The breakpoint SSOT

There are no magic numbers. The mobile breakpoint is a runtime CSS custom property — derived from settings.viewport in your tokens (see Modern CSS) — and the JavaScript reads it from the computed stylesheet (--breakpoint-tablet) instead of hardcoding pixels. CSS media queries, the hamburger toggle, and the JS collapse logic all switch at exactly the same width, and changing settings.viewport moves everything at once. The same alignment goes the other way: WP Rig’s responsive classes share the scale with core’s block-visibility classes (hamburger hides at 481px, nav collapses at 782px), documented so you don’t double-toggle.

Deep submenus overflowing the viewport edge is the classic navigation bug (#845). WP Rig fixes it with a modern hybrid:

  • CSS Anchor Positioning where supported: submenus anchor to their parent item (position-anchor) and auto-align natively — zero JavaScript, zero flicker.
  • IntersectionObserver fallback for non-supporting browsers: an optimized TypeScript observer detects right-edge proximity and applies open-left, with deep submenus inheriting the flip from their grandparent.
  • Third-level-and-deeper submenus align left of their parent (or inherit open-left) via explicit selector groups in _navigation.css — inside an @supports (position-anchor: …) block plus the classic fallback path.

Developer lock mode (Alt + Click)

Debugging a menu that closes when you click into devtools is maddening. Hold Alt/Option while clicking the mobile toggle and the menu locks open (body.mobile-menu-locked) — it will not close when focus moves to dev tools or the element inspector. Clicking the close button releases the lock. The mobile navigation test suite asserts this behavior explicitly.

Testing the navigation

Navigation has the deepest test coverage in the framework — use it when touching navigation.ts or _navigation.css:

npm run test:e2e:mobile-nav        # headless: viewports, 5-level fixtures, containment
npm run test:e2e:mobile-nav:watch  # headed, step-by-step
npm run test:e2e:nav:watch         # full visual watch: hover, keyboard, viewport transitions
npm run test:e2e:spatial            # geometry: overflow, collisions, containment

The mobile-nav suite injects self-contained 5-level submenu fixtures, so results are deterministic no matter what pages exist in your local database. Full details in Testing in WP Rig.

Testing in WP Rig (the suites), Modern CSS with Lightning CSS (viewport scale), and Theme Paradigms (classic vs block navigation markup).