Repository navigation
Description
Summary
When a button with aria-controls points to an element with role="region" and an accessible name, JAWS announces "moved to controlled element" after JAWS key + Alt + M, but the virtual cursor stays on the button.
The same page works when the target is a plain <div>, or a role="region" without a name (which Chromium exposes as generic). So the trigger is the target being a landmark, not the role attribute or the way the name is given: aria-label and aria-labelledby both reproduce it.
The browser exposes the controls relation and the region in all three cases (checked with the Chrome DevTools accessibility panel). The behavior is the same in Chrome and Firefox.
Steps:
- Save the example below as an HTML file and open it in Chrome or Firefox.
- Tab to the "Show region" button and press Enter to expand the content.
- Press JAWS key + Alt + M.
- Repeat for the "Show plain" and "Show unnamed region" buttons.
Expected result
The virtual cursor moves to the controlled element in all three cases, like it does for "Show plain".
Actual result
- "Show region": JAWS says "moved to controlled element", the virtual cursor stays on the button and the next arrow key reads the button again.
- "Show plain": the virtual cursor moves to the content.
- "Show unnamed region": the virtual cursor moves to the content.
Example
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>aria-controls target with role=region</title>
</head>
<body>
<h2>Fails: target is a named region</h2>
<button type="button" aria-expanded="false" aria-controls="regionContent">Show region</button>
<div hidden>
<div id="regionContent" role="region" aria-label="Region details">
<p>Region content.</p>
</div>
</div>
<h2>Works: target is a plain div</h2>
<button type="button" aria-expanded="false" aria-controls="plainContent">Show plain</button>
<div hidden>
<div id="plainContent">
<p>Plain content.</p>
</div>
</div>
<h2>Works: target is a region without a name</h2>
<button type="button" aria-expanded="false" aria-controls="unnamedContent">Show unnamed region</button>
<div hidden>
<div id="unnamedContent" role="region">
<p>Unnamed region content.</p>
</div>
</div>
<script>
document.querySelectorAll('button[aria-controls]').forEach((button) => {
const wrapper = document.getElementById(button.getAttribute('aria-controls')).parentElement;
button.addEventListener('click', () => {
const expanded = button.getAttribute('aria-expanded') === 'true';
button.setAttribute('aria-expanded', String(!expanded));
wrapper.hidden = expanded;
});
});
</script>
</body>
</html>This is the content container of an accordion built after the APG accordion pattern, which recommends role="region" with aria-labelledby pointing to the heading. With that markup, the aria-controls link from the heading button cannot be followed in JAWS.
Additional Information
JAWS version and build number
JAWS 2026.2608.25
Operating System and version
Windows
Browser and version:
Chrome and Firefox, current stable versions, both reproduce the issue.
Activity