Dialogs need a name
- Rule:
axe/aria-dialog-name - Checks: ARIA dialog and alertdialog nodes should have an accessible name
- WCAG: none; a best practice, not a WCAG success criterion
- Fix class:
content: A fix needs authored text.
Who it affects
Section titled “Who it affects”- People who use a screen reader or a braille display, most of them blind.
How to fix it
Section titled “How to fix it”The dialog has a visible title
Section titled “The dialog has a visible title”Point aria-labelledby at the title by its id. Screen readers announce the name as focus moves into the dialog, so people know what opened. A native <dialog> element needs a name the same way.
<div role="dialog" aria-modal="true" aria-labelledby="delete-title"> <h2 id="delete-title">Delete this file?</h2> <p>You cannot undo this.</p> <button type="button">Delete</button> <button type="button">Cancel</button></div>The dialog has no visible title
Section titled “The dialog has no visible title”Add a visible heading and point aria-labelledby at it, so everyone sees the same name. Where the design has no room for one, name the dialog with aria-label in words that say what it is for, such as “Cookie settings”.
aria-labelledby points at an id that is missing or empty
Section titled “aria-labelledby points at an id that is missing or empty”Make sure the referenced element exists, with text, whenever the dialog is shown, and that its id is unique on the page. A dialog component rendered more than once needs a distinct id for each copy.
Fixes that fail
Section titled “Fixes that fail”Naming the dialog for its role, such as aria-label="Dialog" or aria-label="Modal"
Section titled “Naming the dialog for its role, such as aria-label="Dialog" or aria-label="Modal"”Screen readers already announce the role. The name has to say what this dialog is about.
Adding only a title attribute
Section titled “Adding only a title attribute”axe accepts it, but a mouse user then gets a tooltip wherever the pointer rests inside the dialog, and the name is tied to no visible heading.
In React
Section titled “In React”The part of the fix that differs in React, in its syntax. The rest of the guidance holds.
A dialog component hard-codes the id its aria-labelledby points at
Section titled “A dialog component hard-codes the id its aria-labelledby points at”Generate the title’s id with useId inside the component and use it for both id and aria-labelledby, so each dialog on the page finds its own title.
import { useId } from 'react';
function ConfirmDialog({ title, children }) { const titleId = useId(); return ( <div role="dialog" aria-modal="true" aria-labelledby={titleId}> <h2 id={titleId}>{title}</h2> {children} </div> );}Fixes that fail in React
Section titled “Fixes that fail in React”Generating the id with Math.random() or a counter
Section titled “Generating the id with Math.random() or a counter”The value differs between the server and the client, which causes a hydration mismatch, and it changes on every render, which breaks any reference that kept an earlier value. useId stays stable.
More on the rule
Section titled “More on the rule”axe-core’s documentation of the rule
CORA’s fix guidance adapts content from accessibility-agents, under the MIT License: see its notice.