Description
Provide a general summary of the issue here
Consider the following code example
<FocusScope contain>
<ScrollableContainer>
<p id="test">Hello, world!</p>
{/** Lots of text */}
<a href="#test">Scroll back to top</a>
</ScrollableContainer>
</FocusScope>
The issue seems to only occur when contain
is set to true
on the FocusScope
π€ Expected Behavior?
I'd expect that when I click on a hash anchor link, it should be consistent with the default browser behaviour, scrolling to the targeted element.
π― Current Behavior
If I have my acessibility settings to have prefers-reduced-motion
set to reduce
, with the scroll behaviour of the given container being auto
then clicking on the "Scroll back to top" link does nothing.
π Possible Solution
Adding an onclick event for the link similar to the following can resolve the issue. This won't work in Safari, the FocusScope will take control back to the link
and prevent scroll.
(event) => {
const href = e.currentTarget.href;
if (!href.startsWith('#')) return;
document.querySelector(href)?.scrollIntoView();
}
Though this isn't a reasonably scaleable solution.
I've tried using focus()
to force scroll within the FocusScope but I don't like to think what the a11y implications will be.
const scrollToHashHref = (event: React.MouseEvent<HTMLAnchorElement>) => {
const href = event.currentTarget.getAttribute('href')
if (!href || !href.startsWith('#')) return
// Href targets an id, so let's try scroll to that element
const ref = document.querySelector(href)
if (!(ref instanceof HTMLElement)) return
// We need to ensure the element is focusable, focus on it, and then restore it's original focusability
// - FocusScope will refocus on the link, preventing scroll
// - FocusScope will prevent using `focus()` on non-focusable elements in Safari
const initialTabIndex = ref.getAttribute('tabindex')
ref.setAttribute('tabindex', '-1')
ref.focus()
if (initialTabIndex == null) {
ref.removeAttribute('tabindex')
} else {
ref.setAttribute('tabIndex', initialTabIndex)
}
}
π¦ Context
No response
π₯οΈ Steps to Reproduce
Using react-aria
export default function App() {
return (
<>
<FocusScope contain>
<div style={{ height: 40, overflow: 'auto' }}>
<p id="wont">This won't be scrolled to</p>
<p>Lorem ipsum</p>
<a href="#wont">Scroll back to top</a>
</div>
</FocusScope>
<FocusScope contain={false}>
<div style={{ height: 40, overflow: 'auto' }}>
<p id="will">This will be scrolled to</p>
<p>Lorem ipsum</p>
<a href="#will">Scroll back to top</a>
</div>
</FocusScope>
</>
);
}
Version
3.34.1
What browsers are you seeing the problem on?
Chrome
If other, please specify.
No response
What operating system are you using?
MacOS
π§’ Your Company/Team
No response
π· Tracking Issue
No response