Nested Focusable Element
Don't steal focus from a clickable parent by making a child element focusable
What We Check For
Focusable elements should not be nested within clickable parent elements. When a non-interactive child element is focusable, assistive technology focuses on it instead of the clickable parent — meaning the element's interactive role is never announced.
This rule checks all accessibility-focusable controls that are not themselves interactive. If such a control is contained within a clickable parent, it is inherently interactive, but will not announce a role. The element will be flagged as an accessibility violation.
Failing Example ❌
The card is clickable, but the profile picture inside it is separately focusable.
TalkBack does not announce the card's role or "Double-tap to activate" hint, and instead focuses on and announces the inner element.
Users don't know the card is interactive, and the element with focus is not clickable.
Passing Example ✅
The inner element is no longer separately focusable.
TalkBack focuses on the card itself and announces its content, role, and "Double-tap to activate."
Users understand the card is interactive and can activate it.
At a Glance
- This rule has a Critical impact for users of TalkBack and Voice Access
- When a child element steals focus from a clickable parent, the interactive role is lost
- TalkBack will not announce "Double-tap to activate" if the focused element is not itself clickable
- The fix is always to remove focusability from the nested element, not to add a role to it
- Container views that have no action should not be left clickable — this avoids false positives
Impact to Users
When assistive technology does not announce a role, blind or low-vision users relying on TalkBack will not know they can trigger an action. For example, TalkBack focuses on an inner element and announces only its text (e.g. "Theme"). It does not announce that it is a button, or that the user should double-tap to activate. Users are left without the context they need to interact with the screen.
Confirm Nested Focusable Element Issue
- Turn on TalkBack
- Focus on the element and each of its descendants
- One of the following will happen:
- Inaccessible: TalkBack reads the text but does not announce a role or ability to interact
- Accessible: TalkBack reads all text and also announces a role and/or how to interact with the element
Fix Issues
Remove focusability from nested elements so the clickable parent can gain focus and announce its role. Do not add focusable properties to non-interactive descendants of a clickable view.
To avoid a false positive finding, ensure container elements that do nothing when tapped are not left clickable. Our tools cannot determine if a clickable element has an associated programmed action, so we must assume that it does in order to flag potentially inaccessible behavior.
Examine surrounding container elements, such as Frame Layouts, Card Views, or Drawers, to make sure that any element without an associated action is not set as clickable.
XML
In the example below, the MaterialCardView is clickable, but if the child LinearLayout has focusable="true" TalkBack will focus on it instead of the card. In its default state the focusable property of LinearLayout is false. Ensure that is is not set to true, so the card can gain focus and announce its interactive role.
<com.google.android.material.card.MaterialCardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/launch_a_toast"/>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>Compose
In this example, the Card is clickable, but if the child Row has a .focusable() attribute, TalkBack will focus on it instead. Ensure the Row does not have a .focusable() attribute, so the Card can gain focus, announce its text content, and convey its interactive role (e.g."Double-tap to activate").
Card(
modifier = Modifier
.clickable {
launchToast(context)
}
) {
Row(
modifier = Modifier
.padding(10.dp),
horizontalArrangement = Arrangement.spacedBy(10.dp, Alignment.CenterHorizontally)
) {
Text(stringResource(R.string.launch_a_toast))
}
}.NET MAUI
In the example below, the Grid has a TapGestureRecognizer, but it will not be visible to assistive technology if it is hidden via AutomationProperties.IsInAccessibleTree="false". If having the Grid in the accessibility tree conflicts with other functionality, set SemanticProperties.Hint to describe the interaction (e.g., "Button") so TalkBack can announce "Double-tap to activate".
<Grid
HorizontalOptions="FillAndExpand"
RowDefinitions="Auto,Auto"
RowSpacing="10"
VerticalOptions="FillAndExpand">
<Grid.GestureRecognizers>
<TapGestureRecognizer Command="{Binding Function}"/>
</Grid.GestureRecognizers>
<Label
Grid.Row="1"
FontAttributes="Bold"
FontSize="16"
HorizontalOptions="CenterAndExpand"
VerticalOptions="FillAndExpand">
<Label.FormattedText>
<FormattedString>
<Span Text="Text with a clickable parent"/>
</FormattedString>
</Label.FormattedText>
</Label>
</Grid>React Native
In this example, TouchableOpacity has accessibility properties set directly on it. The properties accessible={true} and accessibilityRole="button" ensure assistive technologies announce it as an interactive element, so users understand the content and that it is actionable.
<TouchableOpacity
accessible={true}
accessibilityRole="button"
style={styles.productCard}
onPress={() => navigateTo("product")}
>
<Text>Product Price</Text>
<Text>$10.00</Text>
</TouchableOpacity>Flutter
When a GestureDetector wraps a Card, the Card gains accessibility focus but isn't itself clickable, so TalkBack won't announce "Double-tap to activate". Move the tap handler inside the Card using InkWell so the element that receives focus is also the one that handles the tap.
Card(
child: InkWell(
onTap: () => ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text("Card clicked"),
behavior: SnackBarBehavior.floating,
)
),
child: const Padding(
padding: EdgeInsets.all(16.0),
child: Text(
"Text with clickable parent"
),
),
),
)Can I Ignore This Rule?
Nested Focusable Element has a Critical impact for users, and we strongly recommend fixing this issue. When focus lands on a non-interactive element inside a clickable parent, TalkBack users have no way to know the element can be activated. Ignoring this rule means those users effectively cannot interact with the affected element. Learn more about ignoring rules.
Resources
Deque University Course Pages
Note: Full access to Deque University resources requires a subscription.
Other Resources
- Web Content Accessibility Guidelines (WCAG) 2.1, W3C Recommendation
- WCAG 2.1 Understanding Docs
