Change record status: 
Project: 
Introduced in branch: 
8.x
Description: 

In Drupal 8, we provide a simple way to assist the user in keyboard navigation, to guide the flow of both screen reader users and power users.

Background

The Drupal 8 toolbar needed tabbing management. So did in-place editing. The Overlay module that was introduced in Drupal 7 already had code to deal with this. That code was pulled out of there and abstracted so that it could be used for more advanced use cases.

When to use

Whenever the user is completing a specific task, keyboard navigation (tabbing) should be constrained to the elements relevant to that task.

In Drupal core:

  • Overlay: tabbing should be constrained to the contents of the overlay; the user should not be able to tab to the underlying page.
  • Contextual links: when toggling the "edit mode" (pencil icon) button in the toolbar, all contextual links become visible. To help screen reader users (and power users) navigate more efficiently, tabbing is then constrained to all contextual links on the page; this greatly increases navigation speed.
  • In-place editing: tabbing is constrained to action for in-place editing: navigate only between the fields that are in-place editable and the trigger that allows you to stop in-place editing, and while editing a field: constrain again to actions relevant to editing that field.

And, whenever such a tabbing constraint is active, you should inform the screen reader user of that too: use Drupal.announce() to announce it aurally!

Drupal.TabbingManager automatically handles simultaneous tabbing constraints: it stacks them. So if you first enable the edit mode toggle to jump from one contextual link to the next, then for example edit a view in the overlay, it will remember the previous tabbing constraint (the one for contextual links) and restore it once you're done with the overlay.

How to use

// Constrain to the "edit mode toggle" and contextual links.
var tabbingContext = Drupal.tabbingManager.constrain($('.contextual-toolbar-tab, .contextual'));
// Announce the tabbing constraint.
var args =  {
  '@contextualsCount': Drupal.formatPlural(Drupal.contextual.collection.length, '@count contextual link', '@count contextual links')
};
Drupal.announce(Drupal.t('Tabbing is constrained to a set of @contextualsCount and the edit mode toggle.', args));
Drupal.announce(Drupal.t('Press the esc key to exit.'));

// The task was completed; release the tabbing context.
tabbingContext.release();
// Depending on the use case, announce this as well.

See this DrupalCon Portland presentation for more details: https://portland2013.drupal.org/node/2158.

How to build & debug this? Not familiar with screen readers?

Use the devel_a11y module to visualize tabbing constraints. Whenever the constraints change, an animation will occur. The tabbable elements are marked in red, the currently focused element (if any) is marked in blue.

devel_a11y module visualizing tabbing constraints

AttachmentSize
tabbingmanager.visualize.png73.48 KB
Impacts: 
Module developers
Updates Done (doc team, etc.)
Online documentation: 
Not done
Theming guide: 
Not done
Module developer documentation: 
Not done
Examples project: 
Not done
Coder Review: 
Not done
Coder Upgrade: 
Not done
Other: 
Other updates done