Tech
ARIA Labels: When, Where, and How to Use Them

Sarah Dev
Lead Frontend
Read time
4 min
Published
Nov 15, 2025
There's a golden rule in digital accessibility: 'No ARIA is better than bad ARIA.' Incorrectly implemented ARIA attributes can make the experience worse for screen reader users, not better.
Many developers sprinkle aria-label on elements believing it makes the site more accessible. In reality, this often introduces problems – like overwriting existing accessible text or creating conflicting messages.
In this guide, we clarify the difference between the most common ARIA attributes and show exactly when to use them.
The three key ARIA attributes
There are many ARIA attributes, but these three are the ones you'll use most:
aria-label – Defines a text label directly on the element. Completely replaces the element's visible text for screen readers.
aria-labelledby – Points to the ID of another element whose text should be used as label. References visible text on the page.
aria-describedby – Adds an extra description beyond the label. Read after the label as supplementary information.
The key difference: aria-label replaces visible text, while aria-labelledby references visible text.
aria-label: For elements without visible text
Use aria-label when an element lacks a visible text label. The most common case is icon buttons:
<button aria-label="Close"><svg>...</svg></button>Without aria-label, the screen reader would just say 'button' – the user has no idea what the button does. With the attribute, 'Close, button' is read.
Other good use cases:
aria-label="Open main menu"aria-label="Visit us on Facebook"aria-label="Search the site"Remember: If the button already has visible text, aria-label is NOT needed. It replaces the visible text, which can create confusion if they don't match.
Rule of thumb: Use aria-label only when the element lacks a visible text label. Otherwise, trust the visible text.
aria-labelledby: Reference existing text
Use aria-labelledby when the label already exists on the page as visible text. This is usually better than aria-label because:
Common example – modal/dialog:
<div role="dialog" aria-labelledby="modal-title"> <h2 id="modal-title">Confirm order</h2> ...</div>Screen reader announces: 'Confirm order, dialog'
Another example – form section:
<fieldset aria-labelledby="shipping-heading"> <h3 id="shipping-heading">Shipping address</h3> ...</fieldset>You can also combine multiple IDs separated by spaces to build a composite label.
aria-describedby: Supplementary information
While aria-label and aria-labelledby define what the element is, aria-describedby gives extra information about it.
Most common use – form instructions:
<label for="password">Password</label><input type="password" id="password" aria-describedby="pwd-help"><p id="pwd-help">At least 8 characters, one number, and one special character</p>Screen reader says: 'Password, text box, At least 8 characters, one number, and one special character'
Error messages:
<input type="email" aria-describedby="email-error" aria-invalid="true"><p id="email-error" class="error">Enter a valid email address</p>The difference from aria-labelledby is that description is read as additional information, not as the element's primary name.
Common mistakes to avoid
1. Double labeling
<button aria-label="Submit">Submit form</button> ❌
Here aria-label overwrites visible text 'Submit form'. Screen reader says only 'Submit'. Remove aria-label.
2. Empty links/buttons with only aria-label
Even if screen readers read aria-label, the element remains visually empty. Users with cognitive disabilities or those who zoom see nothing.
3. Misspelled IDs
aria-labelledby="moddal-title" when ID is modal-title ❌
No error message appears – attribute is silently ignored and screen reader gets no label.
4. aria-label on elements that don't support it
aria-label works on interactive elements and landmarks. On a plain <div> or <span>, it's ignored. Add a role or switch to semantic element.
5. Overlooking native HTML
Before reaching for ARIA, ask: Can native HTML solve the problem? A <label> connected to an <input> is always better than aria-labelledby.
Test your site's accessibility
Free scan, no signup required