In this simple modal example, role is set to dialog and focus is received on dialog container when it opens, but NVDA won’t announce the word ‘dialog’ in the beginning. I notice there is potential NVDA issue on this https://github.com/nvaccess/nvda/issues/8620, but I could find several other accessible modal examples where NVDA announces ‘dialog’ such as https://stackblitz.com/edit/stackblitz-starters-tkpczr?file=src%2Fcomponents%2FModal%2FModal.jsx,src%2Fcomponents%2FNewsletterModal%2FNewsletterModal.jsx, https://codesandbox.io/p/sandbox/react-accessible-modal-dialog-forked-ypw7q8?file=%2Fsrc%2FModal%2Findex.js%3A62%2C1-65%2C25 and w3c Modal https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/examples/dialog/. So what’s is wrong with this modal that is preventing NVDA from announcing ‘dialog’?
HTML
<button id="test_button2">
Open Dialog
</button>
<div tabindex="-1" id="test_dialog2" role="dialog" aria-labelledby="test2">
<h2 id="test2">example</h2>
<p>a test paragraph</p>
<button>close</button>
</div>
CSS
#test_dialog2 {
visibility: hidden;
}
#test_dialog2.show {
visibility: visible;
padding: 1em;
box-shadow: 0 0 300px
}
button[aria-hidden] {
opacity: .2;
}
*:focus {
box-shadow: none;
outline: 2px solid blue;
}
JS
var btn2 = document.getElementById('test_button2');
var dialog2 = document.getElementById('test_dialog2');
var btnClose2 = dialog2.querySelector('button');
btn2.addEventListener('click', function () {
dialog2.classList.add('show');
dialog2.focus();
this.setAttribute('aria-hidden', true);
this.setAttribute('tabindex', '-1');
});
btnClose2.addEventListener('click', function () {
dialog2.classList.remove('show');
btn2.removeAttribute('aria-hidden');
btn2.removeAttribute('tabindex');
btn2.focus();
});