Best Practices for Screen Reader Support
Use these best practices to build Alexa Presentation Language (APL) visuals that work well with screen readers for visually impaired users.
Set the accessibilityLabel on responsive components and templates
The responsive components and templates expose the accessibilityLabel
property for interactive objects. Some of these components have multiple properties you should set. For example, the AlexaDetail
template can display multiple buttons. This template includes the following accessibility-related properties:
button1AccessibilityLabel
button2AccessibilityLabel
headerBackButtonAccessibilityLabel
Set the property for each button that you use in the template. When a template or component has a default value for the accessibilityLabel
, you can use that value without making a change. For example, the AlexaRating
responsive component defaults to a string built from the ratingNumber
and ratingText
properties you provide for the component. For example, when the user taps the component rendered by the following code, the screen reader states "3.5 out of five stars for 509 ratings."
{
"type": "AlexaRating",
"ratingSlotPadding": "4dp",
"ratingSlotMode": "multiple",
"ratingNumber": 3.5,
"ratingText": "509 ratings"
}
See the documentation for the component or template to find the accessibilityLabel
default. For responsive components and templates that don't provide a default, be sure to set the available accessibilityLabel
properties.
Label interactive components with accessibilityLabel and role
Label all interactive components with accessibilityLabel
and role
. Interactive components include all touchable and
actionable components:
When you label these components, use the following guidelines.
Buttons and links
Use button
or link
for touchable components that work as buttons. Be consistent in how you use these roles. For example, use button
for components that cause an action on the current document, and use link
for components that navigate the user to a different document.
Use imagebutton
for a VectorGraphic
that uses one of the touchable component handlers, such as onPress
. Also use imagebutton
for Image
components wrapped in a TouchWrapper
.
Custom user interface controls for check boxes, switches, and radio buttons
If you build a custom UI control that works like a check box, switch, or radio button, label the role appropriately:
- Set role to
checkbox
,switch
, orradiobutton
. -
In the logic for your custom control, use the
checked
component property to keep track of the control state. The screen reader uses this property to tell the user if the item is "checked" or "not checked."If you don't use the
checked
property, the screen reader can't inform the user of the control state.
The following example displays a VectorGraphic
shaped like a diamond. The graphic works as a check box and updates the checked
property when the user selects the graphic. When you select this graphic, the screen reader reads out the string "This is a custom control. Check box. Not checked. Double-tap to activate."" When you double-tap to select (check) the check box, the screen reader reads out the string "Checked."
As an alternative to building a custom control, use a pre-built responsive component in the Alexa Design System for APL:
These components set role
and use the checked
property, so they fully support the screen reader. Set the accessibilityLabel
property to a description of the check box, radio button, or switch. If you place the component alongside text, also provide the accessibilityLabel
for the Text
component.
The following example shows AlexaCheckbox
in different colors and sizes.
Label all informative components with accessibilityLabel
Label all informative components with the accessibilityLabel
property. An informative component is a component that displays information the user needs to use the visual, but isn't interactive. Text
components are informative as they display relevant content. An Image
component can be informative if it's critical to understanding the visual content. An image that's purely decorative and doesn't contribute to the meaning of the visual isn't considered informative.
Label list items
When your APL document displays a list of items, the user can swipe and tap through the list to hear a description of each item.
Custom lists (Sequence, GridSequence, or Pager)
You can build a custom list using the Sequence
, GridSequence
, or Pager
components. Set the accessibilityLabel
on each list item that you display with these components.
The following example shows a Sequence
that displays a numbered list of animals. The accessibilityLabel
for each item matches the text of the item. The overall Sequence
also has an accessibilityLabel
to provide a description of the list itself. When you select the first item in the list, the screen reader reads out "One. Dogs."
{
"type": "APL",
"version": "2024.2",
"theme": "dark",
"import": [
{
"name": "alexa-styles",
"version": "1.6.0"
}
],
"mainTemplate": {
"items": [
{
"type": "Sequence",
"height": "100%",
"width": "100%",
"padding": "@marginHorizontal",
"accessibilityLabel": "This is a list of animals. Some might make good pets.",
"numbered": true,
"data": ["Dogs", "Cats", "Birds", "Fish", "Snakes", "Turtles", "Rabbits"],
"item": [
{
"type": "Text",
"text": "${ordinal}. ${data}",
"accessibilityLabel": "${ordinal}. ${data}"
}
]
}
]
}
}
Items in a list can also be interactive. If the list item takes some action when the user selects it, set the role
for the item as well.
Responsive templates for lists
As an alternative to building a custom list, use a pre-built responsive template:
These templates automatically set the accessibilityLabel
for each item based on the properties of the list item. The following example displays an AlexaTextList
with items that have primaryText
, secondaryText
, and a rating
. When you select the first item in the list, the screen reader reads out the string: "Item 1. Dogs. Great pets but plan on lots of walks. Five out of Five stars. Double-tap to activate."
Avoid the AutoPage command when the screen reader is active
The AutoPage
command instructs a Pager
to begin progressing through all the pages automatically. This command is useful for building a slide show that the user can watch without manually changing pages. However, when the screen reader is active, AutoPage
can trigger the pages to change before the screen reader finishes reading the content on a page. This scenario creates a disorienting experience in which the screen reader "jumps" from component to component.
For example, the following document and data source creates a pager that displays a block of text on each page. The onMount
handler runs the AutoPage
command when the document loads. When a device with the screen reader enabled displays this document, the user experiences the following:
First page of the pager displays
VoiceView: This is a block of text to display on the page. If you… (Screen reader begins reading the main text on the page.)
Page changes automatically due to the AutoPage
command and interrupts the screen reader.
VoiceView: Block of text for the second page… (VoiceView begins reading the text on the second page.)
Pager continues to change the pages, regardless of whether VoiceView has finished reading a given page.
To avoid this problem, use conditional logic in the AutoPage
command. Run the command when the screen reader isn't in use. Replace the onMount
in the previous example with this updated version:
{
"when": "${!environment.screenReader}",
"type": "AutoPage",
"componentId": "pagerId",
"duration": 3000,
"delay": 2000
}
Related topics
Last updated: Nov 28, 2023