bootstrap icon indicating copy to clipboard operation
bootstrap copied to clipboard

Modals aria-hidden attribute

Open bravedave opened this issue 1 year ago • 9 comments

Prerequisites

Describe the issue

I'm actually using Brave Beta - Chrome 131.0.6778.14 Beta, checking around this issue seems to be in Beta and Nightly builds; but not the current release

I tested on Chrome beta - same version as my Brave and it exists there

I'm concluding it is an imminent issue

I can see this got mentioned a while back in #29769

The Issue: I've started seeing aria-hidden issues when I close my modals, and have been able to see it on the demo modals at https://getbootstrap.com/docs/5.3/components/modal/

So to replicate the issue I open the modal, then close it using the cross (top right in the modal header) a second or so after the click this appears in the console, I hadn't noticed before today

I've gone back over my code and am consistent with the documentation

Screenshot 2024-11-05 172723

Reduced test cases

The issue exists in my code and can be demonstrated on the getbootstrap.com site

What operating system(s) are you seeing the problem on?

Windows

What browser(s) are you seeing the problem on?

Chrome

What version of Bootstrap are you using?

v5.3.3

bravedave avatar Nov 05 '24 07:11 bravedave

A bit more on this - I'm thinking it is a rising issue

This only occurs when the fade class is set, so it is to do with elements having focus and visible when the aria attribute is set

Is it sensible to move the setting of the aria hidden attribute down to after the css transition has taken place ? I'm thinking the attribute is set too early

This file is js/dist/modal.js

Screenshot 2024-11-06 214339

bravedave avatar Nov 06 '24 11:11 bravedave

It is a rising issue; the same thing happens in Google Chrome (Canary Version 133.0.6840.0). The issue occurs when the fade class is present.

Khuthaily avatar Nov 16 '24 14:11 Khuthaily

It is a rising issue; the same thing happens in Google Chrome (Canary Version 133.0.6840.0). The issue occurs when the fade class is present.

In my previous comment, I mentioned that the issue occurs when the fade class is present. Even though the issue disappears (most of the times), there are (random?) times when the issue occurs even when the fade class is not used. So, I am not sure if the fade class is a factor in this case.

Khuthaily avatar Nov 17 '24 01:11 Khuthaily

I don't know enough to definitively associate it with fade - but am associating it with something retaining focus until after the transition between the events hide.bs.modal and hidden.bs.modal - so have blamed fade I guess

but it is random - it exists in bootstrap 4 too

In a modified bootstrap.js it disappears for me when the aria-hidden line is moved down

bravedave avatar Nov 17 '24 05:11 bravedave

This is an actual issue. I can reproduce this in our standard frontend (Shopware) with all modals. We recently added focus handling for better accessibility to our modals, to return the focus state to the button that opened the modal after it is closed. But the error message still occurs, because we use the hidden.bs.modal event to do so, but it is too late. When using the hide.bs.modal event it won't work because the browser seems to prevent you from focusing elements outside a dialog, which is basically correct from an accessibility standpoint.

I fixed it like this for now:

modal.addEventListener('hide.bs.modal', () => {
    if (document.activeElement instanceof HTMLElement) {
        document.activeElement.blur();
    }
});

If the bootstrap modal keeps using the aria-hidden attribute, it should implement a similar solution or even a better focus handling in general. Some other solution would be to move modal content to a <template> tag to not make it part of the actual accessibility tree while not in use.

Phil23 avatar Nov 25 '24 10:11 Phil23

This is an actual issue. I can reproduce this in our standard frontend (Shopware) with all modals. We recently added focus handling for better accessibility to our modals, to return the focus state to the button that opened the modal after it is closed. But the error message still occurs, because we use the hidden.bs.modal event to do so, but it is too late. When using the hide.bs.modal event it won't work because the browser seems to prevent you from focusing elements outside a dialog, which is basically correct from an accessibility standpoint.

I fixed it like this for now:

modal.addEventListener('hide.bs.modal', () => {
    if (document.activeElement instanceof HTMLElement) {
        document.activeElement.blur();
    }
});

If the bootstrap modal keeps using the aria-hidden attribute, it should implement a similar solution or even a better focus handling in general. Some other solution would be to move modal content to a <template> tag to not make it part of the actual accessibility tree while not in use.

Thank you, @Phil23, for sharing your solution! It works perfectly and helped me better understand the issue.

To make this functionality more global and consistent across our application, I adapted your approach slightly:

window.addEventListener('hide.bs.modal', () => {
    if (document.activeElement instanceof HTMLElement) {
        document.activeElement.blur();
    }
});

This ensures that the focus is managed correctly on all modals without needing to attach the listener to each modal individually

fredyosorio avatar Jan 11 '25 19:01 fredyosorio

I see this without fade class set, I don't think that's necessary for a repro.

jrochkind avatar Feb 19 '25 19:02 jrochkind

This is an actual issue. I can reproduce this in our standard frontend (Shopware) with all modals. We recently added focus handling for better accessibility to our modals, to return the focus state to the button that opened the modal after it is closed. But the error message still occurs, because we use the hidden.bs.modal event to do so, but it is too late. When using the hide.bs.modal event it won't work because the browser seems to prevent you from focusing elements outside a dialog, which is basically correct from an accessibility standpoint. I fixed it like this for now: modal.addEventListener('hide.bs.modal', () => { if (document.activeElement instanceof HTMLElement) { document.activeElement.blur(); } });

If the bootstrap modal keeps using the aria-hidden attribute, it should implement a similar solution or even a better focus handling in general. Some other solution would be to move modal content to a <template> tag to not make it part of the actual accessibility tree while not in use.

Thank you, @Phil23, for sharing your solution! It works perfectly and helped me better understand the issue.

To make this functionality more global and consistent across our application, I adapted your approach slightly:

window.addEventListener('hide.bs.modal', () => { if (document.activeElement instanceof HTMLElement) { document.activeElement.blur(); } }); This ensures that the focus is managed correctly on all modals without needing to attach the listener to each modal individually

It works successfully, thank you

iyikodcom avatar Jun 01 '25 17:06 iyikodcom

I suddenly started getting this issue on my modals. Any plans to fix it?

speller avatar Jun 12 '25 02:06 speller

Solution we are currently using with 5.3 modals.

window.addEventListener('hide.bs.modal', event => {
    event.target.inert = true
})

window.addEventListener('show.bs.modal', event => {
    event.target.inert = false
})

We chose toggling inert over invoking blur() since the latter (shortened example below) might cause unexpected issues for assistive technology users.

window.addEventListener('hide.bs.modal', () => {
    document.activeElement?.blur()
})

mavelo-llc avatar Jul 25 '25 14:07 mavelo-llc

I've noticed this as well. I don't entirely understand why aria-hidden is necessary in the first place. The modal class will add display: none when it's not being shown:

https://github.com/twbs/bootstrap/blob/6d3345b24c7e58ccb3f228d9395996b3c3f5a216/scss/_modal.scss#L39

Isn't that sufficient to hide the modal from screen readers and other accessibility technology?

nwalters512 avatar Aug 12 '25 16:08 nwalters512

I have also encountered the same problem, which I only encountered recently with the update of Chrome. It seems that the old version from a long time ago would not pop up this issue

ajiho avatar Oct 25 '25 17:10 ajiho

Received this same error in our Chrome extension. Also solved my manually triggering the blur.

heaven avatar Nov 10 '25 10:11 heaven

Solution we are currently using with 5.3 modals.

window.addEventListener('hide.bs.modal', event => { event.target.inert = true })

window.addEventListener('show.bs.modal', event => { event.target.inert = false })

I incorporated this neat and idiomatic workaround (thanks for the hint!) as a fix in PR #41867, setting the inert attribute directly in the functions for showing and hiding the modal. My OCD kicked in today and I wanted to get rid of the warnings in the console. After some unsatisfying experiments with .blur(), I settled on the inert attribute approach, as it was also suggested in the warning itself. The PR should address this issue at the source, and hopefully it gets merged :shipit:. Until then the workaround from @mavelo-llc works just fine 👍.

pwntr avatar Nov 11 '25 15:11 pwntr