Bug 239295

Summary: AX: UsableNet re: inconsistency in hidden contents behind aria-modal dialogs
Product: WebKit Reporter: James Craig <jcraig>
Component: AccessibilityAssignee: Nobody <webkit-unassigned>
Status: NEW    
Severity: Normal CC: andresg_22, giacomo.petri, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: WebKit Nightly Build   
Hardware: All   
OS: All   
Attachments:
Description Flags
reduced test case (but does not yet reproduce problem)
none
static page with aria-modal and headings rotor behaviour
none
w3c example with aria-modal and headings rotor beahviour none

James Craig
Reported 2022-04-13 12:20:12 PDT
Bug report from from UsableNet re: inconsistency in hidden contents behind aria-modal dialogs. Platform not specified, presuming a recent Mac release. Quoting: > Previously, VO with Safari "trapped" the user into the element with aria-modal="true" as expected. Today, VO with Safari is behaving inconsistently across multiple websites. This behaviour is happening in particular with elements injected in the DOM after page load. > > For example, trying to navigate the modal example provided by the aria practices (https://www.w3.org/TR/wai-aria-practices-1.2/examples/dialog-modal/dialog.html) VO is still able to navigate the inert content available in the background (content provided outside the element with aria-modal="true"). It wasn't clear from the bug report if he was navigating by FKA Nav (Tab) or VO Nav (e.g. VO+Right). Report used the term "inert" which isn't the same as "hidden" contents behind an aria-modal dialog. True "inertness" can only be achieved with inert="" and/or the dialog API, not aria-modal or aria-hidden. The difference is only relevant to mention here because if full keyboard access tabbing results in focus of hidden content (if focused, by definition it is not inert) then the modal or hidden state should be ignored and the focused element should be exposed to accessibility. That's not true for actual inert content, which should never achieve focus. The linked example is not a good one because it uses some mediocre focus trapping. The focus trapping doesn't really work, and the added complexity makes it a little harder to diagnose. I'm going to work on reducing a test case before further clarification.
Attachments
reduced test case (but does not yet reproduce problem) (929 bytes, text/html)
2022-04-13 12:37 PDT, James Craig
no flags
static page with aria-modal and headings rotor behaviour (868.70 KB, image/png)
2022-04-13 23:25 PDT, Giacomo Petri
no flags
w3c example with aria-modal and headings rotor beahviour (769.76 KB, image/png)
2022-04-13 23:28 PDT, Giacomo Petri
no flags
Radar WebKit Bug Importer
Comment 1 2022-04-13 12:20:24 PDT
James Craig
Comment 2 2022-04-13 12:37:59 PDT
Created attachment 457560 [details] reduced test case (but does not yet reproduce problem) Attached test case results in expected behavior... dialog is modal until the user tabs out of it, then "hidden" content is focused, resulting in invalidation of the aria-modal state.
James Craig
Comment 3 2022-04-13 12:53:03 PDT
I am getting different behavior in the linked URL, but I have not fully diagnosed. https://www.w3.org/TR/wai-aria-practices-1.2/examples/dialog-modal/dialog.html - Most FKA outside of dialog results in looping due to scripted keyboard trap, preventing some FKA testing without a full teardown of the example. - attempted VO Nav to contents *before* the dialog (VO Left) results in looping due to scripted keyboard trap on blur - VO Nav to *after* the dialog (VO Right) does result in VO breaking free of the dialog, as long as JavaScript remains on. The following results in expected behavior: - JavaScript on, VoiceOver off. - click on dialog trigger to show dialog - turn JavaScript off, then turn VO on. VO remains in modal dialog unless the user tabs outside of it. In which case, the aria-modal state is invalidated as expected. That's all the diagnosis I have time for at the moment. My hunch is that the dialog is being created while focus is left outside the dialog, resulting in immediate invalidation of the modal state. My example may not reproduce because the focus() call is in the same event loop as the dialog creation. If hunch is correct, the workaround until a fix is deployed cold be to focus inside the dialog before marking it as modal, or focus in the same runloop instead of a delayed timeout. (Delayed timeout is a common pattern due to prior bugs in various web engines, so the latter is not a feasible workaround proposal.)
Giacomo Petri
Comment 4 2022-04-13 23:25:51 PDT
Created attachment 457597 [details] static page with aria-modal and headings rotor behaviour example of static page without JavaScript interactions and headings rotor behaviour (as expected)
Giacomo Petri
Comment 5 2022-04-13 23:28:34 PDT
Created attachment 457598 [details] w3c example with aria-modal and headings rotor beahviour Example from W3C with aria-modal="true" element hidden on page load (display:none CSS), made visible while interacting with button. Rotor is still displaying the entire list of page headings, instead of showing only ones contained in aria-modal="true" element.
Giacomo Petri
Comment 6 2022-04-13 23:44:38 PDT
Thanks James for the prompt feedback. Quick clarifications about points you mentioned: - in my previous feedback I was referring to VO navigation (VO+Right); - "inert" was intended as "visually inert", content that shouldn't be presented to VO users navigating node by node, due to the aria-modal="true" attribute set to the modal element. I've attached two screenshots highlighting two different examples: - static page behaving as expected (https://giacomop-starterkit-assistive.udev1a.net/h5/giacomotest/aria-modal-vo) - w3c page behaving inconsistently (https://www.w3.org/TR/wai-aria-practices-1.2/examples/dialog-modal/dialog.html) Activating VO Rotor (control + option + command + U): - In first example you will see that only aria-modal="true" content is presented to the user (expected, only aria-modal="true" content should be available within the accessibility tree). - In second example also content available outside the aria-modal="true" element is presented to the user (inconsistent behaviour). Of course, this will be reflected navigating node by node, unless some custom wrong JavaScript implementation.
Note You need to log in before you can comment on or make changes to this bug.