axe-core icon indicating copy to clipboard operation
axe-core copied to clipboard

False positive in aria-hidden focusable rule

Open sfoslund opened this issue 3 years ago • 2 comments

False positive aria-hidden focusable failure is being reported on focus "bumpers", which are meant to send focus back into the modal/focus trap zone but never receive focus themselves. These elements have aria-hidden="true" so those elements are not announced as clickable/interactive elements to screen reader users. This issue seems to be related to https://github.com/dequelabs/axe-core/pull/3407, but not fixed by that PR.

Codepen example repro: https://codepen.io/pankhurinigam/pen/BawPRbQ

Product: axe-core

Expectation: No aria-hidden failures reported on elements that are not meant to be focusable.

Actual: Failures reported.

Motivation: False positive is confusing to users.

sfoslund avatar Mar 31 '22 15:03 sfoslund

Thanks for the issue. This one might be tough to fix, but I have an idea that might work out.

Edit: For future reference: if the element in question has 0 width/height and/or pointer-events: none, we should move it to needs review instead of fail

straker avatar Mar 31 '22 15:03 straker

Like @WilcoFiers mentioned a few weeks ago in #3406, the gold standard would be to be able to base the "treat as incomplete" decision off of whether there's an on focus event listener registered; it's a shame that it's technically infeasible without the stalled https://github.com/whatwg/dom/issues/412 proposal :(

dbjorge avatar Mar 31 '22 17:03 dbjorge

Validated with the latest axe-core develop branch code base, for the below test scripts: aria-hidden-focus rule presenting incomplete results for the,

 <!--Incomplete examples-->
  <div aria-hidden="true" id="target">
   <button onfocus="redirectFocus()">button</button>
    </div>
   <!--returns undefined when all focusable controls have onfocus event-->
  <div aria-hidden="true" id="target">
    <a href="/" onfocus="redirectFocus()">First link</a>
  <a href="/" onfocus="redirectFocus()">Second link</a>
    </div>
<!--returns false when some, but not all focusable controls have onfocus events-->
<div aria-hidden="true" id="target">
 <a href="/" onfocus="redirectFocus()">First link</a>
   <a href="/"">Second link</a>
  </div>
  <!--returns undefined when control has 0 width and height and pointer events: none (focus trap bumper-->
  <div id="target" aria-hidden="true" tabindex="0" style="pointer-events: none"></div>

    <!--returns undefined when control has 0 width and height and pointer events: none (focus trap bumper) -->
    <button id="target" aria-hidden="true" style="pointer-events: none; width: 0; height: 0; margin: 0; padding: 0; border: 0"></button>'

failing at the scripts:

<!--failure examples-->
  <div aria-hidden="true">
    <a href="/" style="position:absolute; top:-999em" onfocus="document.querySelector('input').focus()">First link</a>
  </div>
  <input />
  <fieldset id="target" disabled aria-hidden="true"><legend><input /></legend></fieldset>'
  <fieldset id="target" aria-hidden="true"><input /></fieldset>
  <div id="target" aria-hidden="true"><a href="/" style="position:absolute; top:-999em">Link</a></div>'
  <div id="target" aria-hidden="true"><input type="text" aria-disabled="true"/></div>
  <div aria-hidden="true"><a id="target" href="">foo</a><button>bar</button></div>'

also validated for the pass scripts:

<!--Pass examples-->
    <div aria-hidden="true"></div>
    <button tabindex="-1">Some button</button>
  </div>
  <p id="target" aria-hidden="true">Some text</p>
  <div id="target" aria-hidden="true"><a href="/" style="display:none">Link</a></div>
  <input id="target" disabled aria-hidden="true" /> 
  <fieldset id="target" disabled aria-hidden="true"><input /></fieldset> 
image

padmavemulapati avatar Sep 26 '22 09:09 padmavemulapati