dequelabs / dequelabs/axe-core
False positive: scrollable-region-focusable ignores scroll chaining from focusable elements inside iframes
- Dominant language
- JavaScript
- Stars
- 7.5k
- Forks
- 933
- Avg merge
- 2d 23h
- Merged PRs (30d)
- 17
Description
### Product
axe-core
### Product Version
4.1.3.0
### Latest Version
- [x] I have tested the issue with the latest version of the product
### Issue Description
#### Expectation
No warnings about scrollable regions needing keyboard access.
#### Actual
The `scrollable-region-focusable` rule flags a `div` with `overflow: auto` as failing, even though the region is fully keyboard-scrollable in practice via CSS scroll chaining from a focusable element inside a nested ``.
#### How to Reproduce
1. See `div.fw-block` at https://careers.corrections.govt.nz/ at a viewport width of 500px or less. Alternatively, create a container `div` with `overflow: auto` sized smaller than an `<iframe>` it contains, so the container has genuine horizontal scroll overflow:
```html
<div style="position: relative; width: 100%; height: 300px; overflow: auto;">
<iframe
id="widget-iframe"
name="widget-iframe"
title="widget"
style="position: relative; min-width: 150px; min-height: 150px; width: 500px; height: 300px;"
scrolling="no"
frameborder="0"
src="https://example.com/some-widget-with-a-focusable-button">
```
Ensure the iframe's own document contains no internal scrollable region (i.e. it has no overflow), but does contain a focusable element (e.g., a ``).
2. Run axe-core against the parent document. The `scrollable-region-focusable` rule fails on `div.fw-block`, because it has no focusable descendant in the parent document's flat tree (per the ACT rule this check is based on, https://www.w3.org/WAI/standards-guidelines/act/rules/0ssw9k/proposed/, iframe content is explicitly out of scope for this determination).
3. Manually verify keyboard operability: tab into the focusable button inside the iframe, then press an arrow key in the overflow direction. Because the iframe's own document has no scrollable region to consume the arrow-key scroll, the browser's default scroll-chaining behavior propagates the unconsumed scroll action outward across the frame boundary to the nearest scrollable ancestor in the parent document — `div.fw-block` — which scrolls as a result.
4. Confirm the chaining is genuine and not incidental: remove `overflow: auto` from `div.fw-block` and repeat step 4. The scroll action no longer stops at that element; it continues chaining outward and scrolls the top-level browser viewport instead. This confirms `div.fw-block` was the element actually receiving and consuming the chained scroll input in step 4.
#### Additional context
- This appears to be an intentional limitation of [ACT rule (0ssw9k)](https://www.w3.org/WAI/standards-guidelines/act/rules/0ssw9k/proposed/) that this axe-core rule is based on, which states "This rule only applies to elements who scroll content in the same document... Such scenarios are tested separately," and Inapplicable Example 6 explicitly excludes iframe-embedded scrollable content from the applicability of this rule.
- But in this case, the cross-document scroll chaining causes an element in the *parent* document to become genuinely keyboard-scrollable as a side effect of focus placed inside the iframe.
- Consider whether the rule's descendant-focusable check could account for scroll chaining from an iframe's nested browsing context when that nested document itself has no scrollable region of its own.
Contributor guide
Research direction
Start with the scrollable-region-focusable rule and reproduce the nested iframe case at a viewport width of 500px or less. Verify keyboard focus and arrow-key scroll chaining, then add regression coverage for an overflow container around a non-scrollable iframe with a focusable element. Done means the parent region is not falsely reported while genuinely non-keyboard-scrollable regions remain covered.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- accessibility, testing
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100