[Bug]: [v5] When Talkback is enabled and a modal is displayed, the items below the modal sheet are still accessible by tap and the sheet is not focused
Version
v5
Reanimated Version
v3
Gesture Handler Version
v2
Platforms
Android
What happened?
- When Talkback is enabled Modal is not focused when presented
- Elements below the Modal are accessible.
- When dismissing modal, elements are no longer accessible/focusable (no green marker around them and no announcements)
There was already an issue in v4 #1641 but this issue still persists.
In general the accessibility behavior is questionable. Why is the backdrop accessible? Why is each element accessible. Handle, Container, Background. Content elements are not accessible seperatly.
Reproduction steps
- When Talkback is enabled Modal is not focused when presented
- Elements below the Modal are accessible
- When dismissing modal, elements are no longer accessible/focusable (no green marker around them and no announcements)
Describe what you expected to happen:
- When Talkback is enabled, if user opens Modal, it should get focus automatically
- Elements below the Modal should not be accessible by default (some prop needed maybe)
- After dismissing Modal, elements that were below it should be accessible/focusable again
Reproduction sample
https://snack.expo.dev/@gorhom/bottom-sheet---issue-reproduction-template
Relevant log output
No response
We're having the same issue.
++ Would love a resolution for this as well
Made a patch-package to fix this issue if anyone's interested in a quick fix:
- Added importantForAccessibility prop to BottomSheet, BottomSheetModal, BottomSheetBackdrop, BottomSheetBackground and BottomSheetContainer
- Added logic to the BottomSheetModalProvider to disable accessibility for app child elements while giving accessibility to the modal content.
Based on the suggestions in https://github.com/gorhom/react-native-bottom-sheet/issues/687 Manually focusing the modal does not seem to be necessary once the rest of the content is non-accessible, as the screen reader will jump to the first available element.
@gorhom+bottom-sheet+5.0.6.patch
Gist
I would suggest creating a custom handle for closing the modal that you can make accessible while hiding the backdrop like this:
@marcogravbrot thank you for the patch, works well! 😊
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.
+1 for this, please re-open, this is likely failing accessibility standards
Does not meet accessibility requirements. Please fix asap.
Made a patch-package to fix this issue if anyone's interested in a quick fix:
- Added importantForAccessibility prop to BottomSheet, BottomSheetModal, BottomSheetBackdrop, BottomSheetBackground and BottomSheetContainer
- Added logic to the BottomSheetModalProvider to disable accessibility for app child elements while giving accessibility to the modal content.
Based on the suggestions in #687 Manually focusing the modal does not seem to be necessary once the rest of the content is non-accessible, as the screen reader will jump to the first available element.
@gorhom+bottom-sheet+5.0.6.patchGistI would suggest creating a custom handle for closing the modal that you can make accessible while hiding the backdrop like this:
![]()
Ty mate! I also added accessibilityElementsHidden to the portal children wrapper to achieve same behaviour on iOS:
<PortalProvider>
<View style={{flex: 1}} importantForAccessibility={isModalVisible ? "no-hide-descendants" : "yes"} accessibilityElementsHidden={!!isModalVisible} >
{children}
</View>
</PortalProvider>
This way i fixed the issue on iOS when the bottomsheetbackdrop and bottomsheetbackground had assessible false applied.
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.
Bump, still an issue
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.
Stop using stale bot, this issue does not solve itself if it's ignored. Bump.
const setScreenReaderFocus = useCallback(() => {
if (isWebDesktop || !pressableRef?.current) return;
try {
const pressableElement = pressableRef?.current;
// Get the native node handle of the element
const nodeHandle = findNodeHandle(pressableElement);
if (nodeHandle) {
// This is the most direct way to focus screen readers on an element
AccessibilityInfo.setAccessibilityFocus(nodeHandle);
} else {
}
} catch (error) {
console.log('Error setting screen reader focus:', error);
}
}, [isWebDesktop, pressableRef]);
return (
<BottomSheetModal
{...props}
aria-modal={true}
ref={ref}
accessible={false}
onDismiss={handleOnDismiss}
stackBehavior="push"
onChange={index => {
// Only set screen reader focus when the sheet is fully open (index 0 or greater)
if (index >= 0) {
setTimeout(() => {
setScreenReaderFocus();
}, 100);
}
}}
keyboardBehavior={keyboardBehavior}
bottomInset={bottomInset}
style={[
style.container,
!hasMainPaddingNative ? {paddingHorizontal: 0} : null,
]}
handleStyle={style.indicatorContainerStyle}
backgroundStyle={[
{
backgroundColor: theme.colors.BOTTOMSHEET_BACKGROUND,
},
backgroundStyle,
]}
enableContentPanningGesture={
!isWebDesktop && isWeb ? false : enableContentPanningGesture
}
enablePanDownToClose={enablePanDownToClose}
handleComponent={disableHandleIndicator ? null : BottomSheetHandle}
handleIndicatorStyle={style.handler}
snapPoints={snapPoints}
backdropComponent={renderBackdrop}
android_keyboardInputMode={android_keyboardInputMode}
keyboardBlurBehavior={keyboardBlurBehavior}
enableDynamicSizing={enableDynamicSizing}>
<Pressable
ref={pressableRef}
accessible={false}
accessibilityLabel={accessibilityLabel || "Bottom Sheet"}
testID={`${testID}_pressable`}>
<BottomSheetScrollView
scrollEnabled={false}
showsVerticalScrollIndicator={false}>
<BottomSheetView
style={!detached && {paddingBottom: detachedPaddingBottom}}
accessibilityViewIsModal={true}
importantForAccessibility={'yes'}
testID={testID}>
{children}
</BottomSheetView>
</BottomSheetScrollView>
</Pressable>
</BottomSheetModal>
);
},
);
1.Set accessible={false} on the BottomSheetModal component. 2.Wrap the content (e.g., BottomSheetView and its children) inside a Pressable component with a ref and accessible={false}. 3.Use findNodeHandle from React Native to get the native node handle of the Pressable. This creates a targetable element for Android’s TalkBack to focus on. Set accessible={false} on the Pressable to avoid it being a focus point itself, letting the inner content take focus.
any updates
Confirmed that this is still an issue with RN 0.79.3 and bottom sheet version 5.1.4.
@marcogravbrot I tried your solution and only ran into one issue; it did fix the problem on Android, but then on iOS, my backdrop could be "clicked through" which was the original problem on Android. So the way I fixed this to get it to work on both platforms was only to change the accessible prop in BottomSheetBackdrop to this:
accessible={Platform.OS === 'ios'}
The the final code in your project would be:
<BottomSheetModal
accessible={false}
importantForAccessibility="no"
ref={bottomSheetModalRef}
enableDynamicSizing
enablePanDownToClose
backdropComponent={props => (
<BottomSheetBackdrop
accessible={Platform.OS === 'ios'} // Without this, content behind backdrop can be pressed on iOS (Android is okay)
importantForAccessibility="no"
disappearsOnIndex={-1}
appearsOnIndex={0}
{...props}
/>
)}
>
@gorhom any way to prioritize fixing accessibility ? This is a significant demand in project in 2025.
I have added a console.log here to see which props are passed to BottomSheet component.
I got a first render with my custom props and just after a 2nd render with undefined props. So I loose my accessibility props...
(maybe related to how
Portal works/teleport components ?)
There is also hard coded accessibility label: https://github.com/gorhom/react-native-bottom-sheet/blob/fc3409db0c58590f0bd71b2e5b45a4343242ce66/src/components/bottomSheetBackground/BottomSheetBackground.tsx#L14
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.
not stale
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.
not stale
@gorhom my team is also facing this same issue, and it's leaving us susceptible to legal action. Is there any chance we could prioritize an accessibility fix? These issues make your modal difficult to use by anyone with a screen reader, switch device, or bluetooth keyboard.
guys personaly i used react native modal with some adjustments to look like bottomsheet and works fine , with as much accessibility you want.
I'm still having this issue @5.2.6.
I'm still having this issue @5.2.6.
if you want to see if it fits to your project , i am trying a little bit different appoach with react native's modal component . https://www.npmjs.com/package/rn-modal-bottom-sheet?activeTab=versions
This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.
not stale
@gorhom is there any chance to resolve this issue?