As a career changer, DEV has played a big part in my development as a Software Engineer. The DEV Community Bug Smash seemed like the perfect opportunity to give something back to the community that helped me so much over the past two years.
My open source journey started with Hacktoberfest 2020 and with some small contributions to RubyForGood and upyoura11y. I wrote about that here. I found it very rewarding, and since then I've been trying to stay active and keep up the open source work.
But, to be honest, digging around in a large codebase like DEV's sounded pretty intimidating. So I took my time. I read through the open issues, looking for something that would speak to me. And then I found it.
Describe the bug
Under #1153 we added skip links to all pages in the app. A skip link should be the first element focused on a page when the user presses the Tab key - however, this is only the case in a Forem if you land directly on a URL, and not if you navigate internally, e.g. by a link click.
There are several strategies available to managing focus on route change, but I would suggested the approach Marcy Sutton has written about following user testing with Fable: What we learned from user testing of accessible client-side routing techniques with Fable Tech Labs
The recommendation in that article is to send focus immediately to the skip link on the new page. We will need to experiment with
:focus-visible to ensure that for users who navigated by mouse click, the skip link isn't visible. If this isn't possible, I think an acceptable fallback would be to focus an empty element directly before the skip link, so that once on the new page, the skip link is the first item focused on Tab press.
- Load the home page, and press Tab. You should see the skip link appear
- Activate the skip link by clicking or pressing Enter
- Select a post using the Tab key and press enter to view it
- On the new page, press Tab again
- Notice that the skip link is not the first item focused, and if you want to get to the main post content you have to press Tab multiple more times
- I select an article by keyboard on the home page
- On the new page the skip link is visible and focused
- If I repeat these actions but use the mouse, the skip link is not visible when I arrive on the new page
Navigation can be tricky in an SPA. The DEV team have done well to implement skip links across the website, but there was some work left to do: making sure that they display when the user navigates to a new link using a keyboard. @s_aitchison did an excellent job of describing the problem and the expected result in the GitHub issue, so all I had to do was follow her helpful instructions.
The team had already started a conversation around the issue and I wanted to make sure I fully understood the problem before I committed to smashing this bug. First I got the app running locally, then I took some time to explore it with a screen reader and reproduce the bug.
Once I understood what the expected behaviour should be and why, adding the code was easy. It took a few iterations, but the reviewers were very supportive, gave me lots of useful pointers, and helped me get around the mysterious behaviours of Safari. You can view the pull request below.
What type of PR is this?
- [ ] Refactor
- [ ] Feature
- [x] Bug Fix
- [ ] Optimization
- [ ] Documentation Update
This PR aims to fix an issue where Skip Links only functioned when landing on a URL, not when using the keyboard to access internal links. With the added changes we are now sending focus immediately to the Skip Link when visitors are using a keyboard, and hiding it when a mouse is used.
QA Instructions, Screenshots, Recordings
Tested manually with keyboard and mouse on Edge, Chrome and Firefox. Ran checks using Axe DevTools and ANDI to ensure no unwanted behaviours have been introduced.
- go to the homepage
- use the keyboard to navigate between pages and check that Skip Link appears on every link
- use your mouse to navigate between pages and ensure that Skip Link does not appear
- refresh the page and make sure Skip Link does not appear
- press Tab and make sure Skip Link appears
Additional notes if you can't see the Skip Link in Firefox:
On a Mac, making the Skip Link appear on Mozilla Firefox requires additional configuration. This post describes what you need to do, although there are a few missing steps. Follow the instructions on StackOverflow for setting up the keyboard behaviour on your Mac, then type
about:config in Mozilla's URL bar. When you see the following message:
Changing these preferences can impact Firefox performance or security, click 'Show all' at the top, type
accessibility.tabfocus in the search bar, click the + icon to the right and update the number from 0 to 7, then click the tick icon on the right to save your changes. You should now be able to see the Skip Link on tab.
- [ ] Yes
- [x] No, and this is why: This PR only includes a CSS update and a small change to
base.js.erb. I couldn't find any specs for this file, so I assumed the decision was to not test the behaviour defined here.
- [ ] I need help with writing tests
[Forem core team only] How will this change be communicated?
Will this PR introduce a change that impacts Forem members or creators, the development process, or any of our internal teams? If so, please note how you will share this change with the people who need to know about it.
- [ ] I've updated the Developer Docs and/or Admin Guide, or Storybook (for Crayons components)
- [ ] I've updated the README or added inline documentation
- [X] I will share this change in a Changelog or in a forem.dev post
- [ ] I will share this change internally with the appropriate teams
- [ ] I'm not sure how best to communicate this change and need help
- [ ] This change does not need to be communicated, and this is why not: please replace this line with details on why this change doesn't need to be shared
Apart from the warm, fuzzy feeling that you've done something nice, the most valuable thing you'll get from open source contributions are the lessons you'll learn. Here's what smashing this bug taught me: