About This HTML Issue
The aria-controls attribute establishes a programmatic relationship between a controlling element (like a button, tab, or scrollbar) and the element it controls (like a panel, region, or content area). Assistive technologies such as screen readers use this relationship to help users navigate between related elements — for example, announcing that a button controls a specific panel and allowing the user to jump to it.
When the id referenced in aria-controls doesn’t exist in the document, the relationship is broken. Screen readers may attempt to locate the target element and fail silently, or they may announce a control relationship that leads nowhere. This degrades the experience for users who rely on assistive technology and violates the WAI-ARIA specification, which requires that the value of aria-controls be a valid ID reference list pointing to elements in the same document.
Common causes of this error include:
-
Typos in the
idor thearia-controlsvalue. - Dynamically generated content where the controlled element hasn’t been rendered yet or has been removed from the DOM.
-
Copy-paste errors where
aria-controlswas copied from another component but the correspondingidwas not updated. - Referencing elements in iframes or shadow DOM, which are considered separate document contexts.
The aria-controls attribute accepts one or more space-separated ID references. Every listed ID must match an element in the same document.
How to Fix
-
Verify the target element exists in the document and has the exact
idthataria-controlsreferences. -
Check for typos — ID matching is case-sensitive, so
mainPanelandmainpanelare not the same. -
If the controlled element is added dynamically, ensure it is present in the DOM before or at the same time as the controlling element, or update
aria-controlsprogrammatically when the target becomes available. -
If the controlled element is genuinely absent (e.g., conditionally rendered), remove the
aria-controlsattribute until the target element exists.
Examples
Incorrect: aria-controls references a non-existent ID
<button aria-controls="info-panel" aria-expanded="false">
Toggle Info
</button>
<div id="infopanel">
<p>Here is some additional information.</p>
</div>
This triggers the error because aria-controls="info-panel" does not match the actual id of "infopanel" (note the missing hyphen).
Correct: aria-controls matches an existing element’s ID
<button aria-controls="info-panel" aria-expanded="false">
Toggle Info
</button>
<div id="info-panel">
<p>Here is some additional information.</p>
</div>
Correct: Tab and tab panel relationship
<div role="tablist">
<button role="tab" aria-controls="tab1-panel" aria-selected="true">
Overview
</button>
<button role="tab" aria-controls="tab2-panel" aria-selected="false">
Details
</button>
</div>
<div id="tab1-panel" role="tabpanel">
<p>Overview content goes here.</p>
</div>
<div id="tab2-panel" role="tabpanel" hidden>
<p>Details content goes here.</p>
</div>
Both aria-controls values — tab1-panel and tab2-panel — correctly correspond to elements present in the document.
Correct: Custom scrollbar controlling a region
<div role="scrollbar" aria-controls="main-content" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" aria-orientation="vertical"></div>
<div id="main-content" role="region" aria-label="Main content">
<p>Scrollable content goes here.</p>
</div>
Correct: Controlling multiple elements
The aria-controls attribute can reference multiple IDs separated by spaces. Each ID must exist in the document.
<button aria-controls="section-a section-b">
Expand All Sections
</button>
<div id="section-a">
<p>Section A content.</p>
</div>
<div id="section-b">
<p>Section B content.</p>
</div>
Find issues like this automatically
Rocket Validator scans thousands of pages in seconds, detecting HTML issues across your entire site.
Learn more: