Skip to content

Fix: Escape key dismisses hover-opened submenus (WCAG 2.1 SC 1.4.13)#968

Open
Contributolo wants to merge 2 commits intostellarwp:masterfrom
Contributolo:fix/esc-dismiss-hover-submenus
Open

Fix: Escape key dismisses hover-opened submenus (WCAG 2.1 SC 1.4.13)#968
Contributolo wants to merge 2 commits intostellarwp:masterfrom
Contributolo:fix/esc-dismiss-hover-submenus

Conversation

@Contributolo
Copy link
Copy Markdown

Problem

The Navigation (Adv) Block already handles Escape for submenus opened via toggle button click (keyCode === 27 in kb-navigation-block.js). However, submenus opened via CSS :hover cannot be dismissed with Escape.

The CSS rule responsible:

.wp-block-kadence-navigation.navigation-desktop-orientation-horizontal
    .menu-item:not(.kb-nav-link-sub-click):hover > .sub-menu {
    opacity: 1;
    visibility: visible;
}

Since :hover is a CSS pseudo-class that cannot be removed via JavaScript, pressing Escape while hovering a submenu has no effect.

This violates:

  • WCAG 2.1 SC 1.4.13 (Content on Hover or Focus): "A mechanism is available to dismiss the additional content without moving pointer hover or keyboard focus."
  • WCAG 2.1 SC 2.1.1 (Keyboard): All functionality must be operable through a keyboard interface.

Since June 2025, the European Accessibility Act (EAA) makes WCAG 2.1 AA compliance a legal requirement for commercial websites in the EU.

Solution

  • Track hovered .menu-item-has-children elements via mouseenter/mouseleave.
  • Add a document-level keydown listener for Escape that adds a kb-nav-esc-close class to the deepest hovered menu item.
  • A CSS rule .menu-item.kb-nav-esc-close > ul.sub-menu { display: none !important } overrides the :hover visibility. The !important is necessary because CSS :hover cannot be programmatically disabled.
  • The class is automatically removed on mouseenter (re-hover) or mouseleave (pointer exits), restoring normal behavior.
  • The existing Escape handler for toggle-opened submenus (keyboard focus inside submenu) is unchanged; the new global handler skips if focus is already inside a sub-menu.

Changes

  • src/assets/js/kb-navigation-block.js: Added hoveredItems tracking, initHoverEscDismiss(), and handleHoverEscDismiss().
  • src/blocks/navigation/style.scss: Added .kb-nav-esc-close override rule.

Testing

  1. Open a page with Navigation (Adv) Block containing submenus.
  2. Hover test: Hover a menu item with children -- submenu appears. Press Escape -- submenu closes. Move pointer away and back -- submenu reopens normally.
  3. Keyboard test: Tab into a submenu, press Escape -- submenu closes, focus returns to toggle button (existing behavior, unchanged).
  4. Nested hover: Hover a top-level item, then hover a nested child with its own submenu. Press Escape -- only the deepest submenu closes.
  5. Vertical navigation: Verify vertical orientation is unaffected (hover submenus are not used in vertical mode).

Add functionality to dismiss hover-opened submenus with Escape key.
Add styles for submenu dismissal on Escape key press.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant