Developer Checklist — JavaScript Appendices

Correct code

JS_N_A1: Dynamic menus should be fully accessible to the keyboard, using Tab and Arrow Keys

This example is a dynamic menu which is based on an unordered-list, creating a hierarchical structure that screenreaders can interpret programatically. The structure is also supplemented with structural-labels around the top-level links, and these provide a greater degree of structure and random-access to screenreaders, via their headings reading mode or equivalent.

The menu can be used with the mouse, or with the keyboard via Tab or Arrow Keys. The Tab key moves through all the menu links in source order, automatically opening sub-menu branches whenever their parent link is focused. The Arrow Keys can be used to navigate the menu in two-dimensions, for example using Left-Arrow and Right-Arrow to move between the links in the top-level list (the permanent navigation bar), then Down-Arrow to move down the links in a sub-menu.

The menu also has a couple of extra features that improve overall usability. The first of these is automatic repositioning for the menus, which prevents them from extending outside the viewport. The second is a short delay before opening or closing menus with the mouse, which improves usability by filtering casual mouse movement (i.e. the menu won't open just because your mouse moves briefly over it on the way to something else, or close just because your mouse goes over the edge for a moment).

Live Demo

Use Tab to get to the menu, then Tab or Arrow Keys to navigate inside it. You can also press Escape to send focus back to the Home link:

Main Menu (skip)

In addition to the structural-labels inside the menu list, there's also a heading before the list that describes its purpose for screenreaders, but which is hidden from sighted users with offleft positioning. The heading also contains a skip link that jumps right past the menu, which is bound to the ID of this paragraph (i.e. to the first element after the menu list).

JavaScript Code

The JavaScript code for this example can be found in: JS_N_A1.js

The CSS for this example can be found in: JS_N_A1.css