Improve a11y for tabs
Fixes #3556.
Some of the attributes were already set in #4051. This PR should implement all the recommendations.
I followed the recommendations in the issue, supplemented with these docs on MDN.
- [x] Set
role=tabliston tabs container element - [x] Set
role=tabon each tab - [x] Set
role=tabpanelon each 'tab panel' that contains the actual content for the tab - [x] Set
aria-labelon the tablist - [x] Set
aria-controlsfor each tab to theidof its associated tab panel - [x] Set
aria-labelledbyon each tab panel to theidof its associated tab - [x] Make the
ids ~CamelCase~ PascalCase to give screen readers better clues that they should be read as individual words - [x] Set
tabindex=-1on all inactive tabs - [x] Set
tabindex=0on the active tab - [x] Set
tabindex=0on all tab panels - [x] Set
aria-selectedon the active tab - [x] Use the
arrow keysto navigate through the tabs (wraps) - [x] Use the
homeandendkeys to navigate to the first / last tab
Loose ends
- [ ] The active tab should show that it is focused (@jackmcdade ?)
Questions
- ~Currently the invisible tabs are not accessible using the arrow keys. It is just as easy to include them. Not sure what would be best, any opinions are welcome.~
How do I properly test this? The arrow keys don't seem to do anything and my keyboard doesn't have home and end keys. 🤔
Looks like when the page loads you're focused in the first field. Press shift tab twice (not sure why twice - the first time it focuses the tab content area, weird?) then you should be focused on the tabs. Right/left should go the previous/next tab. fn+right/left is equivalent to end/home.
Seems to work here!
I didn't check to see if my branch checkout was successful – hah! It does work. I think it should definitely include the hidden tabs, but we should improve the UX there too. Needs some thinking. 🤔
Looks like when the page loads you're focused in the first field. Press shift tab twice (not sure why twice - the first time it focuses the tab content area, weird?) then you should be focused on the tabs.
Yes the recommendation is that both the active tab and the visible tab panel (with the actual content) are 'tabable'. I think it makes sense when coming from the outside:
- By pressing the Tab key (coming from some other element on the page) you switch focus to the active tab
- From there you can select the tab you want by using the arrow keys
- Another press on Tab will bring focus to the actual content panel (which may contain more interactive elements).
We have autofocus though on the title field, which leads to the slightly awkward shift tab flow you are describing 🤔
I think it should definitely include the hidden tabs, but we should improve the UX there too. Needs some thinking. 🤔
I agree. Love the 5th example from the top (the one with the 30 tabs) on this page which combines the dropdown and side scrolling. It will also scroll any tab selected from the dropdown (or in our case with the arrow keys too) into view. I like the dropdown on desktop. And side scrolling is very nice interaction on mobile devices. Which tend to be narrow 😄
Edit: The example I am referring to above seems very doable, I would feel comfortable creating that interaction.
https://user-images.githubusercontent.com/4067531/190318030-81153b25-5b64-4591-9527-396f2167323e.mov
That is slick!
- Added keyboard navigation to tabs
- Made the tab buttons scrollable when there are too many of them
- Fixed a bug where clicking on an inactive tab would not focus it, making it impossible to navigate using only the keyboard (tabs were still navigatable with arrow keys)
I just tied up the last loose ends on this one. Ready for review!