HTML Guides for idrefs
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.
Point aria-describedby on the div at the id of the element that holds the description, or remove it, because an empty or whitespace-only value is invalid.
The attribute takes an IDREFS value, a space-separated list of one or more id values. Screen readers announce the text of those elements as the description of the div, usually after its name and role. Hints and error messages are the typical content. A value of "" or " " gives them nothing to read. The validator shows the bad value between the quotes, so the same mistake appears as “” in one report and as spaces between the quotes in another.
This message usually comes with others. A UI component that accepts optional ARIA props often prints all of them on its wrapper div with an empty string as the default, and a single element ends up with id="", role="", aria-label="", aria-labelledby="" and aria-describedby="". Each empty attribute gets its own validator message. Fix the component once instead of every page that uses it. React and Vue leave out an attribute bound to null or undefined but print one bound to "", so pass null when there is no description ID.
aria-describedby is allowed on a plain div without a role (aria-labelledby isn't), so the validator accepts it as soon as the value holds a real ID. It only checks the format, not whether that ID exists on the page, so make sure the referenced element is there. Keep the attribute when the div is something users move into, such as a group of form controls. On a div that only wraps layout, screen readers often skip the description, so delete the attribute.
Invalid example
The shipping hint is on the page, but the empty aria-describedby doesn't point at it.
<div role="group" aria-labelledby="delivery-label" aria-describedby="">
<p id="delivery-label">Delivery speed</p>
<p>Orders placed before noon ship the same day.</p>
<label><input type="radio" name="delivery" value="standard"> Standard</label>
<label><input type="radio" name="delivery" value="express"> Express</label>
</div>
Valid example
The hint has an id and aria-describedby references it, so screen readers can read the hint when focus moves into the group.
<div role="group" aria-labelledby="delivery-label" aria-describedby="delivery-hint">
<p id="delivery-label">Delivery speed</p>
<p id="delivery-hint">Orders placed before noon ship the same day.</p>
<label><input type="radio" name="delivery" value="standard"> Standard</label>
<label><input type="radio" name="delivery" value="express"> Express</label>
</div>
An aria-labelledby attribute on a div must list at least one element ID, so an empty value, or one made only of spaces, is invalid.
The attribute takes an IDREFS value: one or more id values, separated by spaces, that point at the elements whose text names the div. Screen readers use that text as the name of the div, which is often the heading of a dialog or a page region. A value of "" or " " points at nothing, so the div gets no name from it. The validator reports both with the same message and prints the bad value between the quotes, so one report shows “” and another shows spaces between them.
The usual cause is a shared component or template that writes every ARIA attribute on its wrapper div and fills each one only when the caller passes a value. When the caller passes no label ID, the template still prints the attribute, just empty. Change the template so it leaves aria-labelledby out when it has no ID to point at.
When the div has a role that takes a name, such as dialog or region, give the labeling element an id and reference it. When the div has no role, delete the attribute: aria-labelledby isn't allowed on a plain div, and the validator flags that in a separate message too. An empty role="" is invalid as well and gets its own message.
Invalid example
The dialog has a visible heading, but the empty aria-labelledby doesn't reference it.
<div role="dialog" aria-modal="true" aria-labelledby="">
<h2>Sign in</h2>
<p>Enter your email address to continue.</p>
</div>
Valid example
The heading has an id, and aria-labelledby references it, so screen readers announce the dialog as "Sign in".
<div role="dialog" aria-modal="true" aria-labelledby="signin-title">
<h2 id="signin-title">Sign in</h2>
<p>Enter your email address to continue.</p>
</div>
Validate at scale.
Ship accessible websites, faster.
Automated HTML & accessibility validation for large sites. Check thousands of pages against WCAG guidelines and W3C standards in minutes, not days.
1K Weekly
1,000 monthly checks. Cancel anytime.
Get 1K Weekly →Join teams across 40+ countries