HTML Guides for aria-labelledby
Learn how to identify and fix common HTML validation errors flagged by the W3C Validator — so your pages are standards-compliant and render correctly across every browser. Also check our Accessibility Guides.
The aria-labelledby attribute is part of the WAI-ARIA specification and provides an accessible name for an element by referencing the id values of other elements that contain the labeling text. Without the aria- prefix, labelledby is simply an unrecognized attribute that browsers and assistive technologies will ignore. This means your SVG graphic won’t have the accessible label you intended, leaving screen reader users without a meaningful description of the content.
This issue is especially important for <svg> elements because SVG graphics are often used for icons, charts, and illustrations that need descriptive labels for accessibility. Using the incorrect attribute name means the graphic is effectively unlabeled for users who rely on assistive technology.
How to Fix It
Replace labelledby with aria-labelledby on your <svg> element. The attribute’s value should be a space-separated list of one or more id values that reference elements containing the label text.
If you want to label an SVG using text that’s already visible on the page, aria-labelledby is the ideal approach. You can also reference a <title> element inside the SVG itself.
Examples
❌ Incorrect: Using labelledby (invalid attribute)
<h2 id="chart-title">Monthly Sales</h2>
<svg labelledby="chart-title" role="img" viewBox="0 0 200 100">
<!-- chart content -->
</svg>
✅ Correct: Using aria-labelledby to reference an external heading
<h2 id="chart-title">Monthly Sales</h2>
<svg aria-labelledby="chart-title" role="img" viewBox="0 0 200 100">
<!-- chart content -->
</svg>
✅ Correct: Using aria-labelledby to reference the SVG’s own <title>
<svg aria-labelledby="icon-title" role="img" viewBox="0 0 24 24">
<title id="icon-title">Search</title>
<path d="M15.5 14h-.79l-.28-.27A6.47 6.47 0 0 0 16 9.5 6.5 6.5 0 1 0 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5z"/>
</svg>
✅ Correct: Referencing multiple label sources
You can combine multiple id values to build a composite accessible name, separated by spaces:
<h2 id="section-title">Revenue</h2>
<p id="section-desc">Q1 2024 revenue by region</p>
<svg aria-labelledby="section-title section-desc" role="img" viewBox="0 0 400 200">
<!-- chart content -->
</svg>
In this case, a screen reader would announce something like “Revenue Q1 2024 revenue by region” as the accessible name for the SVG.
Tips
- When using aria-labelledby on <svg>, also add role="img" to ensure consistent behavior across screen readers.
- If the SVG is purely decorative, use aria-hidden="true" instead of labeling it.
- The aria-labelledby attribute overrides other labeling mechanisms like aria-label or the <title> element, so use it when you want a specific label to take precedence.
Set a non-empty list of valid ID references in the aria-labelledby attribute on the <a> element, or remove the attribute and provide an accessible name another way.
The aria-labelledby attribute takes an IDREFS value: a space-separated list of one or more element IDs, each of which must be non-empty, exist in the document, and be unique. An empty value ("") violates the ARIA/HTML constraints and triggers the validator error. On an <a> element, aria-labelledby supplies the accessible name for the link by concatenating the text from the referenced elements. If you don’t have IDs to reference, use visible link text or aria-label. Avoid leaving aria-labelledby empty (common with templating when a variable is blank); either omit the attribute entirely or populate it with valid IDs. Remember that aria-labelledby overrides other naming methods, so an empty or broken reference can result in a link with no accessible name.
HTML examples
-
Invalid (what triggers the error)
<a href="/report" aria-labelledby=""></a> -
Fixed by referencing an existing element with a valid id
<a href="/report" aria-labelledby="report-link-text"> <svg aria-hidden="true" viewBox="0 0 16 16"></svg> </a> <span id="report-link-text">View report</span> -
Fixed with multiple IDs (space-separated)
<a href="/apples" aria-labelledby="prefix apples-text"> <svg aria-hidden="true" viewBox="0 0 16 16"></svg> </a> <span id="prefix">Learn more: </span> <span id="apples-text">Apples</span> -
Fixed by using visible text content (no ARIA needed)
<a href="/report">View report</a> -
Fixed by using aria-label for an icon-only link (when no separate label element exists)
<a href="/search" aria-label="Search"> <svg aria-hidden="true" viewBox="0 0 16 16"></svg> </a>
Empty aria-labelledby on the <svg> is invalid because it must reference one or more existing IDs with non-empty, non-whitespace text.
The aria-labelledby attribute takes a space-separated list of element IDs (IDREFS). Each ID must exist in the document and point to elements that provide an accessible name. On <svg>, this is commonly a <title> or other visible text element. If you have no label to reference, either remove aria-labelledby or provide a valid referenced element. Alternatively, use the aria-label attribute with a text string. Do not leave aria-labelledby empty, and ensure IDs are unique and match exactly (case-sensitive). Examples: reference a <title> with an id, or use aria-label directly on the <svg>.
HTML Examples
Example showing the issue
<svg role="img" aria-labelledby="">
<use href="#icon-star"></use>
</svg>
Fixed examples
<!-- Option A: Reference a title by ID -->
<svg role="img" aria-labelledby="starTitle">
<title id="starTitle">Favorite</title>
<use href="#icon-star"></use>
</svg>
<!-- Option B: Use aria-label instead (no referenced IDs needed) -->
<svg role="img" aria-label="Favorite">
<use href="#icon-star"></use>
</svg>
<!-- Option C: Decorative icon (no name) -->
<svg aria-hidden="true" focusable="false">
<use href="#icon-star"></use>
</svg>
The aria-labelledby attribute creates a relationship between an element and the text content that labels it. It works by pointing to the id of one or more elements whose text should be used as the accessible name. When the validator reports that aria-labelledby must point to an element in the same document, it means at least one of the id values you referenced doesn’t correspond to any element on the page.
This typically happens for a few reasons:
- Typo in the id — the aria-labelledby value doesn’t exactly match the target element’s id (remember, IDs are case-sensitive).
- The referenced element was removed — the labeling element existed at some point but was deleted or moved, and the reference wasn’t updated.
- The id exists in a different document — aria-labelledby cannot reference elements across pages, iframes, or shadow DOM boundaries. The target must be in the same document.
- Dynamic content not yet rendered — the element is inserted by JavaScript after the validator parses the static HTML.
This is primarily an accessibility problem. Screen readers and other assistive technologies rely on aria-labelledby to announce meaningful labels to users. When the reference is broken, the element effectively has no accessible name, which can make it impossible for users to understand its purpose. Browsers won’t throw a visible error, so the issue can go unnoticed without validation or accessibility testing.
To fix the issue, verify that every id referenced in aria-labelledby exists in the same HTML document. Double-check spelling and casing. If you reference multiple IDs (space-separated), each one must resolve to an existing element.
Examples
Incorrect — referencing a non-existent id
The aria-labelledby attribute points to "dialog-title", but no element with that id exists:
<div role="dialog" aria-labelledby="dialog-title">
<h2 id="dlg-title">Confirm deletion</h2>
<p>Are you sure you want to delete this item?</p>
</div>
Correct — matching id values
Ensure the id in the referenced element matches exactly:
<div role="dialog" aria-labelledby="dialog-title">
<h2 id="dialog-title">Confirm deletion</h2>
<p>Are you sure you want to delete this item?</p>
</div>
Incorrect — referencing multiple IDs where one is missing
When using multiple IDs, every one must be present. Here, "note-desc" doesn’t exist:
<section aria-labelledby="note-heading note-desc">
<h3 id="note-heading">Important note</h3>
<p id="note-description">Please read carefully before proceeding.</p>
</section>
Correct — all referenced IDs exist
<section aria-labelledby="note-heading note-description">
<h3 id="note-heading">Important note</h3>
<p id="note-description">Please read carefully before proceeding.</p>
</section>
Incorrect — case mismatch
IDs are case-sensitive. "Main-Title" and "main-title" are not the same:
<nav aria-labelledby="Main-Title">
<h2 id="main-title">Site navigation</h2>
<ul>
<li><a href="/">Home</a></li>
</ul>
</nav>
Correct — consistent casing
<nav aria-labelledby="main-title">
<h2 id="main-title">Site navigation</h2>
<ul>
<li><a href="/">Home</a></li>
</ul>
</nav>
If you don’t have a visible labeling element on the page and don’t want to add one, consider using aria-label instead, which accepts a string value directly rather than referencing another element:
<nav aria-label="Site navigation">
<ul>
<li><a href="/">Home</a></li>
</ul>
</nav>
Ready to validate your sites?
Start your free trial today.