Accessability

Dialogs and modals

Dialogs in your web page require some tweaks to your HTML to be accessible.

Modals

A modal is UI that opens above the page. It could be a form where you would input some content, a "popover" with more information or an alert where you would click "Yes" or "No". The code for these are very similar. The difference is the role of the dialog.

When opened, only the modal should be access through tabbing.

Also, notice the tabindex="-1", this makes the dialog (div) programmatically focusable (div's aren't default focusable). When the model opens, the div should be focused. A library for "focus trapping" could also be used to make sure you cannot tab anything outside the modal.

The modal should close if the user clicks the Escape button.

Alerts

Alerts are short messages that require the user's immediate attention. Like a "Are you sure - Yes / No" message.

<div role="alertdialog" tabindex="-1">
...
</div>

Dialog

Dialogs are more "long-lived" modals that could include forms or more content.

<div role="dialog" tabindex="-1">
...
</div>

Markup

This is an example of the HTML code when the modal (in this case an alertdialog) still isn't visible. Preferably, the div with overlay and content is conditionally rendered when the alert should be shown.

<main>
<button aria-haspopup="dialog" aria-expanded="false" aria-controls="modal-dialog">Open</button>
</main>
<div class="overlay" inert>
<div role="alertdialog" id="modal-dialog" aria-modal="true" aria-labelledby="modal-label" aria-describedby="modal-description" tabindex="-1">
<h1 id="modal-label">Are you sure?</h1>
<p id="modal-description">
Are you sure? This application will no longer be accessible and any existing sessions will be expired.
</p>
<button>Yes</button>
<button>No</button>
</div>
</div>

When opening the alert, change to HTML to the following (notice that nothing except the alert content should be tabbable).

<main inert>
<button aria-haspopup="dialog" aria-expanded="true" aria-controls="modal-dialog">Open</button>
</main>
<div class="overlay">
<div role="alertdialog" id="modal-dialog" aria-modal="true" aria-labelledby="modal-label" aria-describedby="modal-description" tabindex="-1">
<h1 id="modal-label">Are you sure?</h1>
<p id="radixmodal-description">
Are you sure? This application will no longer be accessible and any existing sessions will be expired.
</p>
<button>Yes</button>
<button>No</button>
</div>
</div>

Notice the inert attribute on <main>. This makes the browser ignore user input events for the element and it cannot be tab-focused.

To do

  • Use correct aria and role attributes and update when modal i opened/closed.

  • Trap tab focus on the modal when opened.

  • Modal closes with escape-button.

  • Focus modal when opened.