Skip to content

USWDS - Modal: Restore page content when the opener has left the document - #6786

Open
vssinghh wants to merge 1 commit into
uswds:developfrom
vssinghh:modal-restore-aria-hidden-on-close
Open

USWDS - Modal: Restore page content when the opener has left the document#6786
vssinghh wants to merge 1 commit into
uswds:developfrom
vssinghh:modal-restore-aria-hidden-on-close

Conversation

@vssinghh

@vssinghh vssinghh commented Aug 5, 2026

Copy link
Copy Markdown

Summary

Closing a modal now always restores screen reader access to the page. If the element that opened the modal was gone by the time it closed, page content kept aria-hidden="true" and stayed invisible to assistive tech until reload.

Breaking change

This is not a breaking change.

Related issue

Closes #6785

Problem statement

Opening a modal hides everything outside it from screen readers. Closing should undo that, but the undo sat inside if (menuButton && returnFocus).

returnFocus comes from the modal's data-opener attribute. If that element isn't in the document anymore, the lookup returns null and the attributes never come off. You get no modal on screen and a page that's still entirely aria-hidden, with no way out except a reload.

Opening always hid. Closing only sometimes unhid.

Solution

Moved the unhide out of the guard so it always runs, and left returnFocus.focus() inside it.

Focus return can't work if the opener is gone, but that shouldn't keep the page hidden.

I left the menuButton condition on the focus call alone. Dropping it might be fine too, but it would change focus behavior in a case unrelated to this bug. Happy to change it if you'd prefer.

Testing and review

The test removes the clicked opener while the modal is open, closes it, then checks nothing is left with data-modal-hidden. A second opener stays on the page, so menuButton is still truthy and only returnFocus is missing.

npx gulp unitTests: 802 passing. Reverting the fix but keeping the test gives 800 passing, 2 failing, and the only failures are the new test. It runs twice because the spec covers a modal initialized at document.body and at the modal element.

I also checked this outside the unit tests, on a static page with Playwright, against published 3.13.0 and develop. Opener left alone restores fine, opener removed leaks, Escape leaks the same way. Can share that if useful.

Closing a modal only removed aria-hidden and data-modal-hidden from
non-modal content inside an if (menuButton && returnFocus) guard.
returnFocus resolves from the modal's data-opener attribute, so when the
opener is no longer in the document the guard fails and the whole page
stays hidden from assistive technology after the modal closes.

Opening hides unconditionally, so the two paths were asymmetric. Move the
restore out of the guard and leave only the focus call inside it.

Closes uswds#6785
@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

✅ All commits on this PR have a verified signature. Thanks!

@chandracarney chandracarney added the Affects: Accessibility 🟡 Relates to the accessibility of our components label Aug 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Affects: Accessibility 🟡 Relates to the accessibility of our components

Projects

Status: Triage

Development

Successfully merging this pull request may close these issues.

Bug: Modal leaves page content aria-hidden after close when its opener is gone

2 participants