HTML Guides for aria-activedescendant
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-activedescendant attribute tells assistive technologies which child element within a composite widget — such as a combobox, listbox, or autocomplete dropdown — is currently “active” or focused. Instead of moving actual DOM focus to each option, the parent element (like an input) retains focus while aria-activedescendant points to the visually highlighted option by referencing its id. This allows screen readers to announce the active option without disrupting keyboard interaction on the input.
When aria-activedescendant is set to an empty string (""), it creates an invalid state. The HTML and ARIA specifications require that any ID reference attribute either contains a valid, non-empty ID token or is omitted altogether. An empty string is not a valid ID, so the W3C validator flags this as an error: Bad value “” for attribute “aria-activedescendant” on element “input”: An ID must not be the empty string.
This problem commonly occurs in JavaScript-driven widgets where aria-activedescendant is cleared by setting it to "" when no option is highlighted — for example, when a dropdown closes or the user clears their selection. While the developer’s intent is correct (indicating that nothing is active), the implementation is wrong.
Why this matters
- Accessibility: Screen readers may behave unpredictably when encountering an empty ID reference. Some may silently ignore it, while others may announce errors or fail to convey widget state correctly.
- Standards compliance: The ARIA specification explicitly requires ID reference values to be non-empty strings that match an existing element’s id.
- Browser consistency: Browsers handle invalid ARIA attributes inconsistently, which can lead to different experiences across platforms and assistive technologies.
How to fix it
- Remove the attribute when no descendant is active. Use removeAttribute('aria-activedescendant') in JavaScript instead of setting it to an empty string.
- Set a valid ID when a descendant becomes active, pointing to the id of the currently highlighted or selected option.
- Never render the attribute in HTML with an empty value. If your framework or templating engine conditionally renders attributes, ensure it omits the attribute entirely rather than outputting aria-activedescendant="".
Examples
Incorrect: empty string value
This triggers the W3C validation error because the attribute value is an empty string.
<input type="text" role="combobox" aria-activedescendant="" />
Correct: attribute omitted when no option is active
When nothing is active, simply leave the attribute off.
<input type="text" role="combobox" aria-expanded="false" />
Correct: valid ID reference when an option is active
When a user highlights an option, set aria-activedescendant to that option’s id.
<div role="combobox">
<input
type="text"
role="combobox"
aria-expanded="true"
aria-controls="suggestions"
aria-activedescendant="option2" />
<ul id="suggestions" role="listbox">
<li id="option1" role="option">Apple</li>
<li id="option2" role="option" aria-selected="true">Banana</li>
<li id="option3" role="option">Cherry</li>
</ul>
</div>
Correct: managing the attribute dynamically with JavaScript
The key fix in JavaScript is using removeAttribute instead of setting the value to an empty string.
<div role="combobox">
<input
id="search"
type="text"
role="combobox"
aria-expanded="true"
aria-controls="results" />
<ul id="results" role="listbox">
<li id="result1" role="option">First result</li>
<li id="result2" role="option">Second result</li>
</ul>
</div>
<script>
const input = document.getElementById('search');
function setActiveOption(optionId) {
if (optionId) {
input.setAttribute('aria-activedescendant', optionId);
} else {
// Remove the attribute instead of setting it to ""
input.removeAttribute('aria-activedescendant');
}
}
</script>
In summary, always ensure aria-activedescendant either points to a real, non-empty id or is removed from the element. Never set it to an empty string.
Ready to validate your sites?
Start your free trial today.