Skip to main content

HTML Guide

Bad value “” for attribute “aria-controls” on element “a”: An IDREFS value must contain at least one non-whitespace character.

The validator error occurs when an element such as an a, button, or custom widget includes aria-controls="" (empty) or whitespace-only. The aria-controls attribute takes one or more space-separated id values (IDREFS). Each referenced id must exist exactly once in the same document. Leaving it empty violates the ARIA and HTML requirements and provides no usable relationship for assistive technologies.

Why this matters:

  • Accessibility: Screen readers rely on aria-controls to announce relationships between controls and controlled regions (e.g., a toggle and its panel). An empty value misleads AT or adds noise.
  • Standards compliance: HTML and ARIA require at least one non-whitespace id. Empty values cause validation failures.
  • Robustness: Incorrect references can confuse scripts and future maintainers, and break behavior when IDs change.

How to fix it:

  • Only add aria-controls when the element truly controls another region (show/hide, sort, update).
  • Ensure the controlled element has a unique id.
  • Set aria-controls to that id (or multiple space-separated IDs).
  • Keep the reference in sync if IDs change.
  • If nothing is controlled, remove aria-controls entirely.

Examples

Invalid: empty aria-controls (triggers the error)

<a href="#" aria-controls="">Toggle details</a>

Valid: control a single region

<div id="details-panel" hidden>
  Some details...
</div>
<a href="#details-panel" aria-controls="details-panel">Toggle details</a>

Valid: control multiple regions (space-separated IDs)

<section id="filters" hidden>...</section>
<section id="results" hidden>...</section>
<button type="button" aria-controls="filters results">Show filters and results</button>

Valid: remove when not needed

<a href="#">Toggle details</a>

Minimal complete document with proper usage

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>aria-controls Example</title>
  </head>
  <body>
    <button type="button" aria-controls="info" aria-expanded="false">Toggle info</button>
    <div id="info" hidden>
      Extra information.
    </div>
    <script>
      const btn = document.querySelector('button');
      const panel = document.getElementById(btn.getAttribute('aria-controls'));
      btn.addEventListener('click', () => {
        const expanded = btn.getAttribute('aria-expanded') === 'true';
        btn.setAttribute('aria-expanded', String(!expanded));
        panel.hidden = expanded;
      });
    </script>
  </body>
</html>

Tips:

  • Use aria-controls for functional relationships (control affects content), not just visual proximity.
  • Combine with aria-expanded when toggling visibility to convey state.
  • Verify that every id in aria-controls exists and is unique; avoid dynamic mismatches created by templating or component reuse.

Learn more:

Last reviewed: February 13, 2026

Was this guide helpful?

Related W3C validator issues