Accessible Interaction¶
This tutorial will walk through creating the view for a simple interactive web application, with a focus on accessibility.
The end result will look and behave like this:
It is possible to tab into the controls in the view, and manipulate fully with the keyboard. It has the interactive highlights feature enabled, and provides a significant amount of information to screen reader users (as discussed below).
The accessible-interaction-demo repository contains all of the code for this tutorial. The code samples below can be edited directly (and will update the demo above each sample), but the repository can also be cloned and run locally, replacing src/View.ts with the code below.
Setting up the View¶
For the main view, we've provided the BackgroundNode
and CyclistNode
types. We will start with the scaffolding below:
We're creating a View
subtype of Node that will contain a background and a cyclist. This Node will be placed into a Display with animation and events set up.
Adding an Acceleration Slider¶
Next, we'll add a slider to control the acceleration of the cyclist. We'll add an AccelerationSlider
(a HSlider subtype) to the view, within a Panel (which provides a background and padding):
Making the Slider Accessible¶
Scenery creates a Parallel DOM, which is a parallel representation of the scene graph that can be used to provide information to screen readers.
As shown above the last code example, while the slider will show up to screen readers (as a <input type="range">
), it won't be very useful without additional information.
UI components in SceneryStack support the accessibleName
and accessibleHelpText
fields, which can be used to provide additional information to screen readers. We'll add these to the AccelerationSlider
:
Also note that the Parallel DOM will update dynamically based on the scene graph and the data it contains! The value of the slider will be updated in the Parallel DOM as the slider is moved.
This raw value is not very useful to screen readers, so we'll want to customize this. The HSlider mixes in the type AccessibleValueHandler (via AccessibleSlider), which provides pdomCreateAriaValueText
:
This will be much more usable for the user!
Sometimes slider thumbs can be difficult, especially for touch users. While the slider should always be large enough by default, we can invisibly increase the area of the slider thumb for touch users.
Mouse and touch areas can be displayed by calling display.setPointerAreaDisplayVisible( true )
to help visualize. UI components in SceneryStack have custom fields to assist in adjusting these areas, and sliders have thumbTouchAreaXDilation
and thumbTouchAreaYDilation
:
Stop Button¶
We can add a "stop" button to the view, which will stop the cyclist when pressed. Note the accessible information provided:
In addition, we can provide an alert to screen reader users when an action changes state with alertDescriptionUtterance
:
This page will display alerts visually, but screen readers will read them out loud.
Radio Buttons¶
We will also add a control to switch the color of the bicycle frame. We'll use a VerticalAquaRadioButtonGroup, which accepts parameters similar to the slider:
Note how the radio buttons are able to identify the accessibleName
default from the Text nodes provided. Many times this will be possible, and it will not be necessary to provide the accessibleName
field.
High-Level Description¶
We can give the view some high-level structure and description by tagging the view with an h1
element, and providing a description for the scene. It is always recommended to provide a description of what is available to help contextualize what is available.
By placing the descriptionNode
(which has no visual representation) first, it will be read out first by screen readers.
labelTagName
can also be used to add more structure to the controls:
Cyclist Description¶
It is also valuable to add description to the visual elements represented in the scene. We can add a description to the cyclist, which will be read out by screen readers.
Try playing with the cyclist, and see how the description changes:
Pan and Zoom¶
It is possible to add a listener to support pan and zoom for any Node. We will use AnimatedPanZoomListener, and will provide it with the relevant bounds.
The example below should support panning and zooming with touch (both on mobile and desktop):
Accessible Highlights¶
By passing interactiveHighlightsEnabledProperty: true
to the creation of the Display, this will enable the interactive highlights for the view for any interaction, including mouse interation: