Tab-based navigation on Gatsby sites is broken
See original GitHub issueDescription
Gatsby puts page content in a div with tabindex="-1"
which means clicking anywhere in the page resets tab focus back to the top. The normal behaviour is that focus is sent to the focusable element that is nearest to the click.
The div in question is:
<div style="outline:none" tabindex="-1" id="gatsby-focus-wrapper">
I think this is likely an accessibility regression. If not, it is at least a deviation from how tab-based navigation is expected to work.
As I understand this is some trick to achieve focus trapping/locking that is brought over by @reach/router
but it’s not clear to me how this is an improvement over the default behaviour that I see on almost every well-built site I visit (e.g. https://gov.uk - an accessibility champion to me).
Steps to reproduce
- Go to https://gatsbyjs.com and scroll towards the middle of the page then double click to select the word “multiple” as I have done in the screenshot below:
-
Now hit the <kbd>Tab</kbd> key and you should see that the “Skip to content” link at the top of the page is focused (the actual behaviour) instead of the “Explore 2000+ plugins” link in the screenshot (the expected behaviour). It’s quite jarring the lower down the page you are and then hitting tab either intentionally or indavertently only to get sent back to the top of the page.
-
To establish that the current behaviour is broken, in your devtools locate the
#gatsby-focus-wrapper
div and delete thetabindex="-1"
attribute from it. -
Now repeat steps 1 and 2. This time you’ll notice that the focus goes to the “Explore 2000+ plugins” link as expected.
Expected result
Covered in steps to reproduce
Actual result
Covered in steps to reproduce
Environment
System:
OS: macOS 10.15.7
CPU: (12) x64 Intel(R) Core(TM) i7-8750H CPU @ 2.20GHz
Shell: 5.7.1 - /usr/local/bin/zsh
Binaries:
Node: 12.18.1 - /var/folders/11/zcvk9j4j7rd_dj0t5hcv9wc80000gp/T/yarn--1610674348120-0.6652836311657397/node
Yarn: 1.22.5 - /var/folders/11/zcvk9j4j7rd_dj0t5hcv9wc80000gp/T/yarn--1610674348120-0.6652836311657397/yarn
npm: 6.14.10 - /usr/local/bin/npm
Languages:
Python: 2.7.16 - /usr/bin/python
Browsers:
Chrome: 87.0.4280.141
Firefox: 84.0.2
Safari: 14.0.2
npmGlobalPackages:
gatsby-cli: 2.12.87
Issue Analytics
- State:
- Created 3 years ago
- Comments:6 (1 by maintainers)
Top GitHub Comments
This is a huge deal. I’m surprised that more people haven’t noticed or don’t care.
I understand that this is to help screen reader users start at the beginning of a page on route change but what Reach did is pretty annoying. Breaking the standard behavior for users that switch between keyboard and mouse frequently (like me) is no solution. I opted to manually focus to the first h1 in the content container on route change to accommodate screen reader users.
I ended up getting rid of the tabindex in the focus wrapper with this:
Thank you for opening this @disintegrator
Gatsby uses
reach-router
andtabindex
is set there to control focus for screen-reader environments: https://github.com/reach/router/blob/e203fe612236851a0bd3c77dba693e539a351c62/src/index.js#L376I understand that this is confusing but this was discussed previously in-depth here: https://github.com/gatsbyjs/gatsby/issues/7310 and https://github.com/reach/router/issues/63
We will have to replace
reach/router
to actually fix it.I am going to close this as a duplicate because there is nothing actionable on our side at the moment. We can get back to it if we decide to go away from reach-router.