Focus lock not working with VoiceOver/Safari on MacOS
Summary:
It seems to be possible to escape the focus lock with VoiceOver and Safari on MacOS if Quick Nav is turned off. Navigating with left or right arrow key (without VoiceOver modifier key) allows the screen reader cursor to escape the modal. Once a focusable element outside the modal is reached, focus escapes and it is possible to navigate the underlying page with e.g. tab-key.
Steps to reproduce:
- Open Safari on MacOS
- Navigate to https://github.com/reactjs/react-modal#demos / Minimal example
- Turn on VoiceOver, turn off Quick Nav (left+right arrow)
- Trigger / open the modal
- Navigate with left arrow key (without modifier) until cursor reaches the trigger button outside the modal
Expected behavior:
Cursor should stay inside the modal like here (https://www.w3.org/TR/wai-aria-practices-1.1/examples/dialog-modal/dialog.html). Focus should not escape.
Link to example of issue:
https://codepen.io/claydiffrient/pen/KNxgav
Additional notes:
This is pontentially a MacOS/Safari/VoiceOver bug.
EDIT: Please disregard. I was testing on Chrome. 😂 Sigh.
Hey @aappoalander, thank you so much for your bug report, and my apologies to resurrect this old thread. :) We're looking into a similar issue with focus escaping the modal and I wanted to follow up.
I am trying to reproduce the bug using the steps you describe, but I can't seem to replicate what you're seeing. Namely, navigation with arrow keys doesn't seem to do anything at all when the modal in the CodePen is opened and has focus. 🤔
And here are my VoiceOver settings for good measure; specifically the "Commanders" settings to ensure that Quick Nav is off as you describe:
If you still have any memories around this issue or notice that I'm doing something obviously wrong, I would love any pointers to properly reproduce this! 🙇 We're going to be looking into this bug on our end in the meantime.
@aappoalander @doeg This one is going to be trick to debug. Maybe an old macOS or Safari version.
@diasbruno @aappoalander ha, well in terms of "things I'm doing obviously wrong", I was testing this in Chrome. 🙄 -1 to my reading comprehension today. My bad.
I was actually able to reproduce this very easily in Safari 16.5 on macOS 13.4. 🎉 🐛 I'm currently debugging a separate (mostly internal) issue that's preventing us from upgrading to [email protected] (latest) but plan to work on this one after!
I spent some time looking into this and tl;dr I expect this is a bug with older versions of Safari/macOS/VoiceOver rather than an issue with react-modal. (cc @diasbruno)
First, I tried to reproduce it on my work machine with ~ latest macOS + Safari and could not:
- macOS Sonoma 14.3
- Safari 17.3
Reproduction steps:
- Go to https://codepen.io/claydiffrient/pen/KNxgav
- Open modal
- Tab to focus "Close modal" button
- Try left and right arrow keys;
document.activeElementand VO focus stay on the "Close modal" button
https://github.com/reactjs/react-modal/assets/855595/591d411c-8998-4e6a-b442-52e3b2071ffe
See screenshots for VoiceOver settings. I've updated my settings to match upstream bug report, specifically ensuring QuickNav is turned off.
On the other hand, I can reproduce the bug described in the upstream ticket very easily on my personal laptop, which is running older versions of everything:
- macOS Ventura 13.4
- Safari Version 16.5 (18615.2.9.11.4)
Using the same CodePen example and reproduction steps above, note that using the left and right arrow keys from within the modal will have VO start reading out the "Trigger Modal" text behind the modal, however document.activeElement stays on the "Close modal" button as I can press enter to trigger it.
https://github.com/reactjs/react-modal/assets/855595/658f34c2-0599-4db6-9131-49686700944a
Now, the reason I think this is a Safari/VO bug rather than a react-modal bug is I can replicate the same behaviour on the w3.org "aria dialog" example page on my personal machine: https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/examples/dialog/
- Open the "Add Delivery Address" dialog
- Your focus will be in the first input; pressing left and right arrow keys doesn't do anything
- Tab until your focus is on the "Cancel" button
- Press right arrow
- VO starts reading out the "Accessibility Features" heading behind the open dialog
https://github.com/reactjs/react-modal/assets/855595/cdb589fb-8ce9-4730-9ce2-d084ce6973a7
Still on my personal machine (which can reproduce the bug in Safari) and attempting the same repro steps on the w3.org page with Chrome, my VO focus stays within the dialog.
https://github.com/reactjs/react-modal/assets/855595/be080687-8683-4e96-ab7d-332b0b927132
So given the tl;dr above:
tl;dr I can reproduce it reliably but only on an older version of macOS + Safari.
...This does seem like a VO and/or Safari bug on older versions of Safari. Unfortunately, I couldn't find evidence of this bug or its fix in the Apple release notes. 🧐