-
Notifications
You must be signed in to change notification settings - Fork 27.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Routing isn't screen-reader accessible? #7681
Comments
It should focus back on the body already: https://github.com/zeit/next.js/blob/canary/packages/next/client/link.tsx#L183 cc @connor-baer |
I'll have a look later today. The focus behavior should work. The title announcement is new to me, but it sounds like a reasonable addition. I'll do a bit more research. |
This issue should be reopened since #7693 was reverted by ##7753. I've been doing some preliminary research on announcing client-side route transitions. Here's a good article that sums it up nicely: https://hiddedevries.nl/en/blog/2018-07-19-accessible-page-titles-in-a-single-page-app My main takeaways:
IMO, Next.js should provide a reasonable default since many developers probably don't know or think about this. For advanced use cases, this behaviour should be customizable. It would be super helpful to get an actual expert's opinion on this. I will also do more research and share my findings here. |
We reverted the PR as it was merged right before Next.js 9 so it wasn't on canary long enough to be considered stable. @Timer is going to re-apply it later. |
My 2¢ here (I'm by no means an accessibility expert): For arbitrary client-side navigation, it doesn't seem like it will be possible to know that a URL change indicates large content replacement, since that's highly application dependent.
Since this issue goes pretty deep on Accessibility concerns, I asked @robdodson. Rob wrote about similar things a couple years back, and I will try to paraphrase the suggestions he and I discussed: Resetting focus back to starting point is desirable, but you need to have a logical starting point to focus. Just blurring elements won't cause screen readers to announce new content, and focussing So here's an alternative approach I'd like to float: give developers a convenient (and perhaps default) way of marking their focus root, then detect and focus it when performing client-side navigation. As a reference point, Gatsby appears to do this for their client-side navigation. Here's a rough example of what might go on // move focus back to the focus root if one has been provided:
const focusRoot = document.querySelector('[next-focus-root]');
if (focusRoot) focusRoot.focus(); That selector could be pretty easily added by developers, and potentially part of the default /** @example
* const { Component, pageProps } = this.props
* <div id="app">
* <Header />
* <FocusRoot><Component {...pageProps} /></FocusRoot>
* </div>
*/
export function FocusRoot(props) {
return <div next-focus-root style="outline:none" tabindex="-1" role="group" {...props}>;
} ... or developers could annotate their desired focus root with the |
Just an update, Marcy happened to publish a post about this yesterday! It's definitely worth a read, and there's a whole section on the above: |
Blind regular screen reader user here! :) I was comparing reactJS and other server side rendering solutions for a project I am working on. Focus handling is a critical accessibility issue in most of the server side rendering solutions I've tested until now. I think that nextJS should automatically move focus on the first accessible element of the newly appeared component (the route destination) after completing the route transition. A mechanism should be also provided to allow developers to easily indicate where focus should be moved after navigating to a new route to handle edge cases and/or customize the default behavior (perhaps even opting out from it) wherever it makes sense to do so. Finally, when going back to a previously visited route (for instance using the browser's back button) focus should be automatically restored to the point it was before navigating to a new route (I would suppose 99.9% of the times the Link element that triggered the navigation event). Feel free to ask me any question if you need more details; I'd be happy to test eventual patches, but don't feel confident enough with the framework for a PR (yet). |
Hi! I was wondering if there was any plan to reintroduce this back into Next? We're having problems with screen readers not recognising that routing has taken place :/ |
After looking into this problem for a while, we noticed that However, having This can be worked around by adding the attribute on This is in our
|
Feel free to send a PR to improve this! |
Related: Marcy has done some excellent research here on this topic! |
- Update tables to add tbody (HTML validation issue) - Add lang to HTML - Focus on body when navving between pages - Add aria-describedby to charts Sources: - vercel/next.js#7681 - https://www.gatsbyjs.com/blog/2019-07-11-user-testing-accessible-client-routing/
# Route Announcements ## Summary This PR improves the accessibility of NextJS's client-side navigation by announcing route changes to screen readers. ## Context When a user who is sighted clicks on a link, they can see the content change. It's an affirmation that what the user intended to do by clicking a link actually worked! Users navigating the page via a screen-reader will not get this feedback on NextJS sites (This is an issue on many SPA-like architectures). https://user-images.githubusercontent.com/4213649/103017382-63b02b00-44f8-11eb-9940-fb530d2d3018.mov ## Solution Whenever there is a route change, the new `<RouteAnnouncer />` will look for a name to give the new page and then announce it! The name is found by first looking for an `h1`, falling back to `document.title`, and lastly to `pathname`. `<RouteAnnouncer />` is a visually hidden component placed within the `<AppContainer />`. ## Demo https://user-images.githubusercontent.com/4213649/103017401-6ad73900-44f8-11eb-8050-b3e9a7e0c3f2.mov ## Inspiration First and foremost, this PR was inspired by @marcysutton's studies and writing, [What we learned from user testing of accessible client-side routing techniques with Fable Tech Labs ](https://www.gatsbyjs.com/blog/2019-07-11-user-testing-accessible-client-routing/) as well as @madalynrose's [Accessible Routing](gatsbyjs/gatsby#19290) PR for Gatsby. There were also learnings gleaned from the conversations within #7681. ### Related Issues & PRs - Resolves #7681 - Relates to #19963
@olpeh I had to add the following,
in order to make it work. Without it, next/router does not focus on the body. |
I think my workaround only worked in an older version of next, where that body focusing happened in the |
This issue has been automatically locked due to no recent activity. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you. |
Bug report
I was browsing my next.js app with voiceover on, and noticed that client-side route changes aren't announced or even noticed by the screen reader. This is kind of alarming, since I've been using it in production on the assumption that the routing was accessible (my bad, was confusing with gatsby's use of reach-router).
I don't see many other references to "accessible routing" or "screen readers" in the issue history or documentation.
To Reproduce
With voiceover (perhaps other screen readers too) on, click a next/link.
Expected behavior
Focus should move to the top of the new page, and the new page title should be announced by the screen reader, like with a server-side route change, when clicking a next/link.
I'm not a regular screen reader user, so it's possible I'm missing something and the current implementation is actually fine, but I think the point is that the server behaviour and client-rendered behaviours should be the same?
System information
The text was updated successfully, but these errors were encountered: