Skip to main content

Aria Describedby

A name tells you what something is. Sometimes that is not enough. A password field is "Password," but you also need to know the rules. A button is "Delete recipe," but you also need to know it cannot be undone. A field has an error, and you need to know what to fix.

That extra help is a description, and aria-describedby is how you attach it. Like aria-labelledby, it points to text that is already on the page. The difference is what the text is for: not to name the control, but to give it more help.


What You Will Learn​

  • The difference between a name and a description
  • How aria-describedby works
  • How to use it for form hints, errors, warnings, and dialog text
  • How to build an accessible tooltip (WCAG 1.4.13)
  • Why a description can be missed, and what to do about it
  • How to keep descriptions accurate when the page changes
  • How to check your descriptions

The Big Idea​

index.html
<!-- A hint for a form field -->
<label for="pw">Password</label>
<input id="pw" type="password" aria-describedby="pw-hint">
<p id="pw-hint">At least 12 characters.</p>

<!-- A hint and an error together -->
<label for="email">Email address</label>
<input id="email" type="email" aria-invalid="true"
aria-describedby="email-hint email-error">
<p id="email-hint">We only use it to send your receipt.</p>
<p id="email-error"><strong>Error:</strong> Enter an email address that includes an @ sign.</p>

<!-- A warning for a button -->
<button type="button" aria-describedby="del-note">Delete recipe</button>
<p id="del-note">This cannot be undone.</p>

<!-- A dialog with a name and a description -->
<div role="dialog" aria-labelledby="dlg-title" aria-describedby="dlg-text">
<h2 id="dlg-title">Delete recipe?</h2>
<p id="dlg-text">This will remove Rye bread for everyone on your team.</p>
</div>

Pick each example in the lab. Change which help text is included, and turn off descriptions to hear what happens to people who do not receive them.

Name or Description?​

NameDescription
AnswersWhat is it?What else should I know?
LengthShort: a word or a fewA sentence or two
Attributearia-label, aria-labelledby, labelaria-describedby
If it is missingThe control is unlabelled, which is a serious failureThe control still works, but with less help
Example"Password""At least 12 characters."
HeardFirst, with the roleAfter the name, role, and state

A good test: if the text identifies the control, it is a name. If it helps you use the control, it is a description.

How It Works​

The value of aria-describedby is a list of ids, separated by spaces, just like aria-labelledby. The browser finds each element, takes its text, joins the pieces in the order listed, and passes the result to assistive technology as the accessible description.

  • It is read after the name, role, and state. A screen reader typically says: "Password, edit text, protected. At least 12 characters."
  • Hidden text counts, just as it does for names. A referenced element that is hidden is still used. (But see below: hidden help is no help to sighted people.)
  • Missing ids are ignored, silently.
  • The order matters. List the hint before the error, or the other way round, to suit how you want it read.
  • Formatting is lost. A description is read as plain text. Links, buttons, lists, and bold inside it are flattened, and cannot be used. Keep descriptions simple.
  • It is separate from the name. aria-describedby does not change the name. Do not use it to repair a missing name.
  • Many elements can share one description. Several fields can point to the same note ("All fields are required").

Common Uses​

Form hints​

Put formats, rules, and examples in a hint, and connect it. Show it above or beside the field, so everyone sees it before typing. See Accessible Forms.

Error messages​

Add the error to the field's aria-describedby, and set aria-invalid="true". The next time the field is focused, the error is read as part of the description.

Warnings and consequences​

A button that deletes, pays, or sends should say so: "This cannot be undone," "You will be charged 20 dollars."

Dialog text​

A dialog is named by its heading (aria-labelledby), and described by its body text (aria-describedby). That way, when the dialog opens, the screen reader announces both. For urgent confirmations, use role="alertdialog" with the same pair. See ARIA Roles.

Tooltips​

A tooltip is a description, not a name. Point to it from the control. More on this below.

Data and complex content​

A table or a chart can point to a paragraph that explains it: aria-describedby="chart-summary". For a long, structured description (with headings, lists, and links), look at aria-details, which points to real, navigable content. Its support in screen readers is more limited, so do not depend on it alone, and always keep the information in the visible page.

Descriptions Can Be Missed​

This is the most important thing to know about aria-describedby:

  • Many screen reader users turn descriptions off or reduce them, because they can be long and repeated.
  • Descriptions are not read when you move through a list of links, buttons, or form fields, or when you read a page line by line without focusing a control.
  • Descriptions can be read late, after a short pause, and may be cut off when the user presses a key.
  • Changes may not be re-read. If the description changes while the control is focused, a screen reader may not announce it again.

So:

  1. Never put essential information only in a description. If something is required, say so in the label or the visible text ("Password (required)"). Use the description for extras.
  2. Always show the same help on screen. A description should connect text that everyone can see, not hide text that only some people hear.
  3. For urgent news, such as an error that appears while someone is typing, use a live region (see ARIA Live Regions) as well, or move focus, as shown in Focus Management.

Keeping Descriptions Up to Date​

Descriptions that appear and disappear (errors, character counts) need care:

  • Add the error's id to aria-describedby when the error appears, and remove it when it is fixed. Otherwise, a stale reference points at an empty or hidden element.
  • Or keep the element in the page, and change its text. An empty element gives an empty description.
  • Use aria-invalid="true" only while the error is real.
  • Do not point to elements that are removed from the page. Recreate them with the same id, or update the reference.
// When an error appears
input.setAttribute("aria-invalid", "true");
input.setAttribute("aria-describedby", "email-hint email-error");
error.textContent = "Error: Enter an email address that includes an @ sign.";

// When it is fixed
input.removeAttribute("aria-invalid");
input.setAttribute("aria-describedby", "email-hint");
error.textContent = "";

Tooltips and WCAG 1.4.13​

A tooltip is a small box of help that appears when you hover over or focus a control. Done badly, it is a trap: it vanishes when you try to reach it, it covers content, and keyboard users never see it. WCAG 1.4.13 (Content on Hover or Focus) sets three rules:

  1. Dismissible: there is a way to close it (usually Esc) without moving the pointer or the focus.
  2. Hoverable: the pointer can move onto the tooltip without it disappearing (important for people who magnify the screen).
  3. Persistent: it stays until the person moves away, dismisses it, or the information is no longer valid.

And for keyboard users: it must appear on focus, not only on hover.

index.html
<span class="has-tip">
<button type="button" aria-describedby="help-tip">Help</button>
<span role="tooltip" id="help-tip">Opens the help centre in a new tab.</span>
</span>

<script>
const wrap = document.querySelector(".has-tip");
const tip = document.getElementById("help-tip");
tip.hidden = true;

const show = () => { tip.hidden = false; };
const hide = () => { tip.hidden = true; };

wrap.addEventListener("mouseenter", show); // hover (the wrapper includes the tooltip)
wrap.addEventListener("mouseleave", hide);
wrap.addEventListener("focusin", show); // keyboard focus
wrap.addEventListener("focusout", hide);
wrap.addEventListener("keydown", (event) => {
if (event.key === "Escape") hide(); // dismissible
});
</script>

Also remember that touch screens have no hover. If the help matters, make it visible text in the page, rather than a tooltip. And keep a tooltip to plain text: if it has links or buttons, it is a popup or a dialog, and needs a different pattern.

  • aria-description is a newer attribute that lets you write a description as a string, in the same way aria-label writes a name. Support has been growing, but it is not yet as reliable as aria-describedby, and it is invisible and may not be translated. Prefer pointing to real text.
  • aria-details points to richer content, as mentioned above.
  • title can act as a tooltip, and as a fallback description when a control already has a name. It is not shown to keyboard or touch users, so do not depend on it.
  • aria-errormessage is designed for errors, but support is patchy. aria-describedby with aria-invalid is the safer choice today.

Check Your Descriptions​

The checker below finds the usual problems: references to ids that do not exist, duplicate ids, empty referenced elements, links or controls inside a description, descriptions that repeat the name, invalid fields with no message, placeholders used as hints, and tooltips that nothing points to.

http://127.0.0.1:5500/index.html

On a real site, you can also:

  1. Open DevTools, select a control, and look in the Accessibility panel. Many browsers show the computed description.
  2. Use a screen reader, Tab to each field and button, and listen for the description after the name.
  3. Try it with descriptions turned off (most screen readers have a verbosity setting), and see what is lost.
  4. Trigger every error, and check that the description changes when the error appears and disappears.
  5. Test tooltips with a keyboard, a pointer, and a magnifier.

Good Habits​

  1. Use a name for what it is, and a description for extra help.
  2. Keep descriptions short and plain, with no links or formatting.
  3. Show the same help on screen that you connect with aria-describedby.
  4. Never put essential information only in a description.
  5. Link errors only while they are showing, and set aria-invalid to match.
  6. Use unique ids, and check every referenced id exists.
  7. Back urgent messages with a live region or focus.
  8. Make tooltips dismissible, hoverable, persistent, and visible on focus.
  9. Test with a screen reader, with descriptions on and off.

Accessibility Checklist​

  • Every id in every aria-describedby exists, is unique, and has text.
  • Descriptions hold extra help, not the name.
  • Anything essential is also in the label or the visible text.
  • Hints and errors are visible on the page, as well as connected.
  • Invalid fields have aria-invalid and a linked, specific error message.
  • References to errors are added and removed as the errors appear and disappear.
  • Descriptions are short, plain text, with no links or buttons.
  • Tooltips appear on focus and hover, can be dismissed, and can be hovered.
  • Dialogs have both a name and a description where it helps.
  • The page was tested with a screen reader and a keyboard.

Security and Privacy Notes​

  • Descriptions are read aloud and are in the page source. Do not put private data, account details, or internal notes in them.
  • Be careful with error text. A description such as "This email is already registered" tells anyone, including attackers, who has an account. Many sites use a general message and explain it elsewhere.
  • Password help is fine, but do not reveal the exact rules an attacker could exploit, or the user's current password in any form.
  • Do not use descriptions to mislead. A description that contradicts the visible text ("This is free" when it costs money) is deceptive, and it harms people who cannot see the screen.
  • Do not hide warnings only in descriptions. Consent, charges, and privacy terms must be visible to everyone, and not read out only to some people.
  • Clean user-supplied text before placing it in a described element, to prevent script injection.
  • Tooltips from third parties (embedded widgets) can add misleading text. Check what they show.

Global Audience Notes​

  • Translate descriptions with the rest of the page. Because they point to real text, translation tools handle them well, which is an advantage over aria-description.
  • Keep them short and in plain language. They are heard once, in a second language for many people, and long text is easily lost.
  • Show formats clearly: "Date: day/month/year," with an example. Formats such as dates, phone numbers, and decimals differ across regions.
  • Right-to-left languages: check how punctuation and mixed text (numbers, Latin words) read, and that tooltips appear on the correct side.
  • Set the lang attribute on the page, and on any description in another language, so the voice reads it correctly.
  • Low connectivity and old devices: do not rely on a script to show help that matters. Put hints in the HTML, visible from the start.
  • Cultural differences: avoid idioms and jokes in help text. A literal, polite sentence travels best.

Common Mistakes to Avoid​

  1. Using aria-describedby instead of a label.
  2. Essential information only in the description.
  3. A typo in the id, so nothing is described.
  4. Pointing to an empty element.
  5. Links and buttons inside the described text.
  6. Leaving an old error linked after it is fixed.
  7. An error with no aria-invalid, or aria-invalid with no message.
  8. Descriptions that repeat the name.
  9. Hidden help that sighted people cannot see.
  10. Tooltips that only show on hover, or cannot be dismissed.
  11. Long, paragraph-length descriptions.
  12. Never testing with descriptions off.

Practice Time​

Try these in your browser and your editor:

  1. Use the description builder with each example, and turn descriptions off. What does the listener lose?
  2. Add the error to the password example, and explain when its id should be added and removed.
  3. Use the tooltip lab with each option off in turn, and write down which rule it breaks.
  4. Run the checker on the messy HTML, fix every problem, and run it again.
  5. Add a hint and an error to a form field in a page you built, and test with a screen reader.
  6. Give a "Delete" button a description that explains the consequence.
  7. Name a dialog with aria-labelledby, and describe it with aria-describedby.
  8. Replace a title tooltip with a proper tooltip that works with a keyboard.
  9. Find a site with a tooltip that vanishes when you move the pointer onto it. Which rule does it break?
  10. Bonus: build a form field whose description updates as the error is added and removed, with a live region for the change.

Quick Recap​

Click a question to check your answer.

1. What is the difference between a name and a description?

A name says what a control is, in a few words. A description adds extra help, such as a rule or a warning, in a sentence or two. It is read after the name, role, and state.

2. What does aria-describedby take as its value?

A list of ids of elements already on the page. Their text is joined, in order, to make the description.

3. Why should essential information not live only in a description?

Many screen reader users turn descriptions off, and descriptions are not read when moving through lists of links or fields. Essential facts belong in the label or visible text.

4. How should you handle an error that appears and disappears?

Add the error's id (and aria-invalid="true") when it appears, and remove them when it is fixed. Back urgent errors with a live region or focus.

5. What are the three rules for tooltips in WCAG 1.4.13?

They must be dismissible (for example with Esc), hoverable (the pointer can move onto them), and persistent (they stay until you move away or dismiss them).

6. What happens to links inside described text?

They are flattened into plain text, and cannot be used. Keep descriptions simple, and use aria-details or visible content for anything richer.

Key Takeaways​

  • A name says what it is. A description says what else you should know.
  • aria-describedby points to text already on the page, in the order you list the ids.
  • Descriptions can be missed. Never put essential information only in one, and always show help on screen.
  • Keep them short, plain, and accurate. Add and remove error ids as errors come and go.
  • Tooltips must be dismissible, hoverable, persistent, and visible on focus, as well as hover.
  • Use aria-invalid and a linked message for errors, with a live region or focus for urgent ones.
  • Test with a screen reader, with descriptions on and off.

Next, learn how to hide things from assistive technology, and when not to, in aria-hidden.