Accessibility (a11y)
Windows uses the UI Automation framework to provide accessibility information to screen readers.
Microsoft UI Automation is an accessibility framework for Windows. It provides programmatic access to most UI elements on the desktop. It enables assistive technology products, such as screen readers, to provide information about the UI to end users and to manipulate the UI by means other than standard input. UI Automation also allows automated test scripts to interact with the UI.
UI Automation Overview
Uno.UI implements a subset of UWP's UI Automation APIs, to make your applications work with each platform's built-in screen reader or accessibility support:
Windows | Android | iOS | macOS | WebAssembly |
---|---|---|---|---|
Narrator | TalkBack | VoiceOver | VoiceOver | OS or Web Browser Integrated |
Read Expose basic accessibility information to learn how to use the AutomationProperties
supported by Uno.UI:
AutomationProperties.AutomationId
AutomationProperties.Name
AutomationProperties.LabeledBy
AutomationProperties.AccessibilityView
SimpleAccessibility mode
While we were trying to replicate UWP's behavior on iOS and Android, we realized that iOS doesn't allow nested accessible elements to be focused. For example, if you select a list item, the screen reader will automatically read the accessible name of all inner elements one after the other, but won't let you focus them individually (unlike Windows and Android).
While this behavior comes with its own set of limitations (e.g., you can't nest buttons), it greatly simplifies the implementation of accessibility. By comparison, on UWP, the user would need to navigate through every inner element of every list item, unless the developer manually disables focus for each inner element and aggregate their accessible names into a single string to use as the accessible name of the list item.
Instead of trying to replicate UWP's behavior on iOS (which might be doable using the UIAccessibilityContainer
interface, although we haven't tried it yet), we decided to go along with the iOS behavior and bring it to Android as well. We called this mode SimpleAccessibility.
Here's how to enable it:
// App's constructor (`App.cs` or `App.xaml.cs`)
#if __IOS__ || __ANDROID__ || __MACOS__ || __WASM__
FeatureConfiguration.AutomationPeer.UseSimpleAccessibility = true;
#endif
We highly recommend using this mode, as iOS still won't let you focus nested accessible elements even if you don't (see known issues).
Disabling accessibility text scaling
You have the option to disable accessibility text scaling of iOS and Android devices but Apple recommends to keep text sizes dynamic
Here's how to disable it
// App's constructor (`App.cs` or `App.xaml.cs`)
Uno.UI.FeatureConfiguration.Font.IgnoreTextScaleFactor = true;
AutomationId
The AutomationProperties.AutomationId
attached property can be used by UI Testing frameworks to find visual elements.
To avoid performance issues, this property only has an effect when either the IsUiAutomationMappingEnabled
msbuild property, or Uno.UI.FrameworkElementHelper.IsUiAutomationMappingEnabled
is set to true.
Setting this property does the following:
- On Android, it sets the
View.ContentDescription
property - On iOS, it sets the
UIView.AccessibilityIdentifier
property - On macOS, it sets the
NSView.AccessibilityIdentifier
property - On WebAssembly, it sets
aria-label
and thexamlautomationid
property on the HTML element. Therole
HTML Attribute is also set based on the XAML view type whoseAutomationProperties.AutomationId
was set.
This property is generally used alongside Uno.UITest to create UI Tests, and is particularly useful to select items using data-bound identifiers.
Windows.UI.ViewManagement.AccessibilitySettings
Some external libraries or UI toolkits may depend on the AccessibilitySettings
class to check for high contrast settings. As Uno Platform targets cannot check for this via accessible APIs, the properties only return predefined defaults, unless you override them manually via WinRTFeatureConfiguration.Accessibility
:
var accessibilitySettings = new AccessibilitySettings();
accessibilitySettings.HighContrast; // default - false
accessibilitySettings.HighContrastScheme; // default - High Contrast Black
// Override the defaults
WinRTFeatureConfiguration.Accessibility.HighContrast = true;
WinRTFeatureConfiguration.Accessibility.HighContrastScheme = "High Contrast White";
accessibilitySettings.HighContrast; // true
accessibilitySettings.HighContrastScheme; // High Contrast White
When the value of WinRTFeatureConfiguration.Accessibility.HighContrast
is changed, the AccessibilitySettings.HighContrastChanged
event is raised.
Known issues
Hyperlink
inTextBlock
is not supported.TextBox
andPasswordBox
don't useHeader
andPlaceholderText
.ItemsControl
doesn't useAutomationProperties.Name
on itsDataTemplate
's root.There are XAML code generation conflicts between
x:Name
andAutomationProperties.Name
.A child with the same accessible name as its parent is accessibility focusable.
Control
doesn't receive focus when accessibility focused.TabIndex
is not supported.On iOS, nested accessible elements are not accessibility focusable.
On Android, both
ToggleSwitch
and its nativeSwitch
can be accessibility focused.On Android, both
TextBox
and its nativeEditText
can be accessibility focused.On Android,
Control
without a non-empty accessible name is not accessibility focusable.On Android, the accessible name of the native back button can't be customized.
On Android,
TextBox
andPasswordBox
don't hint at "double tap to edit".On Android, you can tap to focus an accessible child of an accessible element that has never been focused even if
UseSimpleAccessibility
is enabled.AutomationPeer.GetLocalizedControlType()
is not localized.FlipViewItem
reads "double tap to activate" even if it's not interactive.Navigating through accessible elements can slow down when the UI is complex.
You can't cycle through
FlipView
items using accessibility focus.There is no way to control or predict accessibility focus following a navigation (page or modal).
Control
s don't announce state changes.Only the following elements support accessibility:
Button
CheckBox
FlipViewItem
ListViewItem
HyperlinkButton
Image
PasswordBox
RadioButton
TextBlock
TextBox
ToggleButton
ToggleSwitch
Only the following
AutomationProperties
are supported:AccessibilityView
LabeledBy
Name
On Wasm, only the following elements support accessibility:
Button
CheckBox
Image
RadioButton
TextBlock
TextBox
Slider
On Wasm,
PasswordBox
is not currently supported due to external limitations.
Tips
- Always set and localize
AppBarButton.Label
(even if it's not displayed on Android and iOS). It is used by the screen reader for accessibility. - Always localize
AutomationProperties.Name
. The name of the resource should look like this:MyButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name
. - Avoid using
Opacity="0"
andIsHitTestVisible="False"
when you can useVisibility="Collapsed"
. The screen reader can still focus the former, but not the latter. - Avoid stacking
TextBlock
s inside aPanel
when you can useInlines
inside aTextBlock
(usingLineBreak
if necessary). This allows the screen reader to read all the text at once, instead of having the user select every part manually. - Use a converter to trim long text. While a
TextBlock
might ellipsize long text, the screen reader will read the entire text provided. - Avoid creating custom controls when you can use built-in ones. If you must, make sure to implement and provide an appropriate
AutomationPeer
. - You can disable accessibility focus of native elements using
android:ImportantForAccessibility="No"
andios:IsAccessibilityElement="False"
. ContentControl
based controls (Button
,CheckBox
, ...) automatically use the string representation of theirContent
property. In order for theAutomationProperties.AutomationId
property to be selectable, addAutomationProperties.AccessibilityView="Raw"
to the control as well.
Enabling the screen reader
Narrator (Windows)
- Press Windows key and Enter at the same time.
VoiceOver (iOS)
- Launch the Settings app from your Home screen.
- Tap on General.
- Tap on Accessibility.
- Tap on VoiceOver under the Vision category at the top.
- Tap the VoiceOver switch to enable it.
TalkBack (Android)
- Launch the Settings app from your launch screen.
- Tap on Accessibility.
- Tap on TalkBack.
- Tap the switch to enable it.
- Tap the OK button to close the dialog.
VoiceOver (macOS)
- Launch the System Preferences from the macOS logo.
- Tap on Accessibility.
- Tap on VoiceOver under the Vision category at the top.
- Tap the Enable VoiceOver switch to enable it.