[Spec] Implement IsInSemanticTree property for accessibility
See original GitHub issueImplement IsInSemanticTree property for accessibility
Create a property that determines whether a specific element (and its children) are in the semantic tree for accessibility. This influences whether or not screen readers can access and read aloud in-app elements.
This property is reminiscent of the Xamarin.Forms AutomationProperties.IsInAccessibleTree property. However, IsInSemanticTree goes beyond the boolean and with a greater scope, will enable developers to have more control over the accessibility of each element in their apps.
API
SemanticProperties.IsInSemanticTree
Properties
API | Description |
---|---|
IsInSemanticTree | iOS: isAccessibilityElement, accessibilityElementsHidden; Android: importantForAccessibility |
public enum IsInSemanticTree
{
Default,
IncludeNode,
RemoveNode,
RemoveSubtree
}
IsInSemanticTree.Default
Every .NET MAUI control will have a Default
value of being in the semantic tree (IncludeNode) or being outside of the semantic tree (RemoveSubtree). Developers will be able to use this property in complex/nuanced scenarios where straying from the defaults will enable them to make their apps more accessible (see example below).
IsInSemanticTree.IncludeNode
IncludeNode
ensures the specified element is in the semantic tree and will be accessible to screen readers. It is the opposite of RemoveNode.
IsInSemanticTree.RemoveNode
RemoveNode
ensures the specified element is NOT in the semantic tree and will NOT be accessible to screen readers. It is the opposite of IncludeNode.
IsInSemanticTree.RemoveSubtree
RemoveSubtree
ensures the specified element AND any children it may have are NOT in the semantic tree and will NOT be accessible to screen readers. This is the equivalent of setting RemoveNode to the specified element, and every single one of the specified element’s child elements.
Implementation Details
Enum | iOS | Android |
---|---|---|
IncludeNode |
isAccessibilityElement=true |
importantForAccessibility=yes |
RemoveNode |
isAccessibilityElement=false |
importantForAccessibility=no |
RemoveSubtree |
accessibilityElementsHidden=true |
importantForAccessibility=noHideDescendants |
Scenarios
XAML Example
<Label Style="{DynamicResource Glyph}" Text="" SemanticProperties.IsInSemanticTree="RemoveNode" /> // renders heart icon
<Label Text="Heart" />
The above sample renders two labels - one as a heart icon, and one as the text “Heart”. By default, all labels are in the semantic tree and therefore screen reader accessible. Therefore, without the setting of SemanticProperties.IsInSemanticTree="RemoveNode"
, screen readers would focus on both the icon and the text. In this case, where the text already describes the icon, it is unnecessary to focus on the icon at all (by default, the screen reader would focus on it and confusingly read back nothing; if a semantic description is set to it, it would read back information that is already captured by the text, thereby making it redundant). In this scenario, manipulating whether or not a control IsInSemanticTree allows for a more accessible experience.
Further considerations and areas of investigation
- Nested controls
- With layouts: My current thinking here is that IncludeNode/RemoveNode just won’t affect anything; RemoveSubtree will just make all the children inaccessible, essentially applying RemoveNode to all of the children individually.
- When RemoveSubtree is set on a parent and IncludeNode is set on any child, which will take precedence? My current thinking is that in this scenario, the RemoveSubtree on the parent will take precedence and all the children will be set to RemoveNode no matter what.
- Semantic grouping APIs will be further deliberated independent of this property
- Interaction with other SemanticProperties
- Should the setting of other SemanticProperties (i.e. Description, Hint, IsHeading, LabeledBy) influence the setting of IsInSemanticTree? Current thinking here is yes - if any of these properties are set, IsInSemanticTree=IncludeNode by default. For example, an image with SemanticProperties.Description set, will also have IsInSemanticTree=IncludeNode set, despite defaults.
- Interaction with related APIs
- Keyboard navigation APIs. What should be the relationship between screen reader accessibility via touch navigation vs. keyboard navigation? The answer varies natively from platform to platform. This spec is currently only defined for screen reader accessibility via touch navigation.
- Related APIs include Android’s focusable, focusableInTouchMode, screenReaderFocusable, among others. Current thinking is that these APIs will be exposed separately, if anything, and will not be integrated into this IsInSemanticTree API.
Difficulty: [medium]
Issue Analytics
- State:
- Created 2 years ago
- Reactions:2
- Comments:5 (1 by maintainers)
After conversations with the team and @llevera we feel that these APIs don’t currently make sense for the current MAUI timeline.
We’ve added the following spec https://github.com/dotnet/maui/issues/1214
That will address mapping to
accessibilityElementsHidden=true | importantForAccessibility=noHideDescendants
Love this concept! Accessibility by default.