I am using the javascript library vex to output dialogs like this
When I used this with a screen reader (narrator), that text is not read so I tried to change the javascript inside vex that manipulates the DOM.
The resulting DOM became like this
<div class="vex vex-theme-default" role="dialog">
<div class="vex-content">
<form class="vex-dialog-form">
<div class="vex-dialog-message" tab-index="0"
aria-label="Login failed">Login failed!</div>
<div class="vex-dialog-input"></div>
<div class="vex-dialog-buttons">
<button type="submit"
class="vex-dialog-button-primary btn vex-dialog-button vex-first">Ok</button>
</div>
</form>
</div>
</div>
but the message "Login failed" is not read even with this markup.
Why not?
(I have also called .focus()
on the div with the class vex-dialog-message
).
The screen reader will instead continue to read the text after the button that was pressed when trying to login (that is running an ajax request that tries to login so the document is never reloaded).
This is what role="alert"
is for.
It will interrupt a screen reader (as it is the equivalent of aria-live="assertive"
) with any immediately important information.
As this is a dialog you may instead want to look at role="alertdialog"
to replace your role="dialog"
.
Additionally when you focus the alert don't make the "Login Failed!" text tabindex="0"
.
Instead use tabindex="-1"
so that you can still focus it programatically but it does not end up in the focus order of the page.
The pattern you currently use will be tricky (not impossible) to get right as your "OK" (submit) button is within a form, so this will send screen readers into "forms mode", which behaves differently from normal reading mode.
As such if you are able to create a custom component there is a great writeup from deque on how best to implement an alertdialog
An example of the markup used there is as follows, notice the use of aria-describedby
and aria-labelledby
to maximise the chances of the alert being read correctly:
<div role="alertdialog" aria-labelledby="alertHeading" aria-describedby="alertText">
<h1 id="alertHeading">Warning! Street Address Mismatch!</h1>
<div id="alertText">
<p>The street address you entered does not match the Postal Code Data.</p>
<p>Is this the correct format: 12345 Main St. Blvd.?</p>
</div>
<button id="yes">Yes, Format Is Correct</button>
<button>No, Edit Street Address</button>
</div>