This document is in beta. Help us by reporting issues via Github or email
On this page:
Make sure that interactive controls receive focus in an order that makes sense, when users navigate through them with the keyboard.
Actionable items should receive the keyboard focus in an order that makes sense for users, and makes the interface easy to operate.
This ensures that content can be navigated in a logical way by screen reader users, keyboard users and Switch device users.
Screen readers go through elements on a page/screen in the order in which they appear in the Document Object Model (Web) / View Hierarchy (iOS and Android), which is a tree-like structure that contains all the elements on the page.
2.4.3 Focus Order: If a Web page can be navigated sequentially and the navigation sequences affect meaning or operation, focusable components receive focus in an order that preserves meaning and operability. (Level A)
This applies to native apps by replacing “Web page” with “screen”.
See the W3C’s detailed explanation of this guideline with techniques and examples.
On the designs that you give to developers, and in conversations with them, indicate what the ‘keyboard focus order’ should be for interactive elements.
This section needs a review and more content. Contribute via Github or email.
The best practices for grouping and ordering elements in an accessible manner can be summarized as follows:
The view hierarchy order and on-screen positioning determine grouping and ordering of text in spoken feedback.
You should group non-focusable items in a focusable container to have them read as a single item.
To logically group related items, it is sometimes necessary to create nested ViewGroup elements (eg: a wrapping RelativeLayout for a label and its value)
<LinearLayout
...
orientation="vertical">
<RelativeLayout
...
android:focusable="true">
<TextView
... />
<TextView
... />
</RelativeLayout>
<RelativeLayout
...
android:focusable="true">
<TextView
... />
<TextView
... />
</RelativeLayout>
<RelativeLayout
...
android:focusable="true">
<TextView
... />
<TextView
... />
</RelativeLayout>
</LinearLayout>
This section needs a review and more content. Contribute via Github or email.
Flutter deals with assistive technologies like screen readers using the Semantics()
widget. For a quick introduction of the Semantics()
widget you can read this article.
##
There are ways of affecting the order for custom navigation of elements with a screen reader. By passing a SemanticSortKey
to the sortKey
property of Semantics()
the element with the lower key value will be read first.
Column(
children: <Widget>[
Semantics(
sortKey: OrdinalSortKey(1), // will be read/focused second by the screen reader
child: SecondWidget()
),
Semantics(
sortKey: OrdinalSortKey(0), // will be read/focused first by the screen reader
child: FirstWidget()
),
]
),
Focus can be controlled using a FocusNode()
:
FocusNode myFocusNode;
@override
void initState() {
super.initState();
myFocusNode = FocusNode();
}
@override
void dispose() {
myFocusNode.dispose(); // Clean up your focus node by disposing it when the widget is disposed
super.dispose();
}
// A widget with the focus node
TextField(
focusNode: myFocusNode,
);
// Focusing the focus node using a fuction call
() => FocusScope.of(context).requestFocus(myFocusNode),
<div>
<h3>Shipping Address</h3>
<label for="n1">Name</label><input type="text">
<label for="a1">Address</label><input type="text">
...
</div>
<div>
<h3>Billing Address</h3>
<label for="n2">Name</label><input type="text">
<label for="a2">Address</label><input type="text">
...
</div>
<table>
<tr>
<td>Shipping Address</td>
<td>Billing Address</td>
</tr>
<tr>
<td>
<label for="n2">Name</label>
<input type="text">
</td>
<td>
<label for="n1">Name</label>
<input type="text">
</td>
</tr>
<tr>
<td>
<label for="a1">Address</label>
<input type="text">
</td>
<td>
<label for="a2">Address</label>
<input type="text">
</td>
</tr>
</table>
tabindex
tabindex
.<h1 tabindex="-1">I'm the heading for a modal dialog</h1>
...
<div tab-index="0" class="fake_button" aria-role="button">Button Label</div>
<div tab-index="3" class="fake_button" aria-role="button">Button Label</div>
position
order
property or flex-direction: reverse;
;position
absolute
, fixed
or sticky
, be careful to not detach the visual order of elements from the order in which they appear in the DOM;tabindex
has been used with a value other than -1
or 0
.inert
attribute)This document is in beta. Help us by reporting issues via Github or email