Skip to content
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

Reevaluate tab navigation interaction pattern #23706

Closed
jelbourn opened this issue Oct 7, 2021 · 7 comments · Fixed by #24062
Closed

Reevaluate tab navigation interaction pattern #23706

jelbourn opened this issue Oct 7, 2021 · 7 comments · Fixed by #24062
Labels
Accessibility This issue is related to accessibility (a11y) area: material/tabs P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent

Comments

@jelbourn
Copy link
Member

jelbourn commented Oct 7, 2021

We currently support two interaction patterns for our tabs component: tablist + tab + tabpanel, and nav + anchor.

We've received feedback that the nav + anchor pattern can be confusing, since it looks like tabs, but behaves differently.
Furthermore, if these two interaction patterns are mixed, the inconsistency can be confusing for users. These issues would affected users with some degree of vision that use assistive technology to supplement their experience.

We should explore ways to reduce or eliminate the confusion here. Some options include (but are not limited to):

  1. Eliminate the nav + anchor pattern and exclusively use tablist + tab + tabpanel. (i.e. deprecate and remove MatTabNavBar)
  2. Change the visuals of the nav + anchor pattern such that it's more visually distinct
  3. Keep both patterns, but add additional guidance and/or checks to ensure that users aren't introducing confusing behaviors, such as assertions that nav-tabs apply focus management or warning if both are used in the same app.
  4. Change nav-tabs to use tablist + tab while still using anchor elements and routing for the content (i.e., keep MatNavTabBar, but change its interaction pattern)

It's worth mentioning that using anchors is desirable for use cases where you want the URL to change and/or want to support opening in new browser tabs. Using routing to drive tab navigation also easily fits into Angular's route-based lazy-loading system.

cc @zelliott

@jelbourn jelbourn added P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent Accessibility This issue is related to accessibility (a11y) area: material/tabs labels Oct 7, 2021
@zelliott
Copy link
Collaborator

zelliott commented Oct 8, 2021

What's the difference between bullets 1 and 4? Is 1 remove/deprecate <nav mat-tab-nav-bar> and 4 change it to the tab / tablist pattern?

I scoured the web for some relevant discussion around this design pattern and links that look like tabs:

GOV.UK

There's a lot of good discussion from the GOV.UK team on this.

Other articles

  • Here's an article explaining why ARIA tabs are dangerous, and you should prefer to use a list of links instead.
    • However, here's a thorough takedown of that article by TPG and some prominent members of the ARIA community, where they argue for using tab / tablist. However, both this article and the one it argues against seem to be discussing ARIA tabs on in-page links.
    • Here's an Inclusive Components article on tabbed interfaces, but again it appears to be limited to in-page links.
    • Here's an article on how to distinguish tabs from site navigation.

I'm tempted to explore bullet points 2 and 3 a bit. There are plenty of examples around the web of "tab-looking" widgets are just implemented as navigation links. For example:

GitHub

image

Google Search

image

Facebook

image

GOV.UK

image

@jelbourn
Copy link
Member Author

jelbourn commented Oct 8, 2021

What's the difference between bullets 1 and 4? Is 1 remove/deprecate

and 4 change it to the tab / tablist pattern?

Yeah, that was what I meant to convey; I updated the original to clarify.

Based on some of those examples, I have a feeling it would be worth raising this to the Material Design team to explore option two above (changing the visuals of nav tabs) so that, while they kind of look like tabs in general, they're distinctive from the thing that the specification calls tabs (i.e., introduce a new component).

@zelliott
Copy link
Collaborator

@jelbourn Just so that I don't forget - one thing that might be worth doing in the meantime is removing the arrow key behavior between links in mat-tab-nav-bar. The links are already separate tab stops, the arrow key behavior is not discoverable to SR users as it is non-standard for links within a navigation landmark, and it may conflict with SR navigation commands.

@zelliott
Copy link
Collaborator

zelliott commented Dec 2, 2021

After some internal discussion, we've decided to try and run with 4: keep MatTabNavBar, but change its interaction pattern to follow the ARIA tabs pattern. The fact that the two tab components are essentially visually indistinguishable, but have very different interaction patterns, was deemed to be extremely confusing and worth resolving now. I say "try and run with" because I wouldn't be surprised if we hit significant technical challenges with this refactor. More specifically, option 4 involves:

  1. Update matTabNavBar to be an ARIA tablist.
  2. Update matTabLink to be an ARIA tab.
  3. Update the tablist to be a single tab stop and in general be a managed focus region (i.e. home and end to hop between first and last tab).
  4. Update each tab to activate on space (it currently only activates on enter).
  5. Update each tab to apply aria-selected when selected.
  6. Update each tab to have aria-controls pointing to the associated tabpanel.
  7. Wrap the associated outlet in an ARIA tabpanel.
  8. Update the tabpanel to have aria-labelledby pointing to the selected tab.

These requirements are taken from https://www.w3.org/TR/wai-aria-practices-1.2/#tabpanel. Requirements 6-8 will be the most difficult to land because there is currently no tabpanel element. Just leaving this comment here for future reference.

@zelliott
Copy link
Collaborator

zelliott commented Dec 3, 2021

A few options @crisbeto and I discussed:

  1. Update MatTabNavBar's API to allow the user to content project an outlet inside of it. If outlet is projected, MatTabNavBar has ARIA tab interaction. Otherwise, it has the default ARIA link interaction. Backwards compatible. Wouldn't allow content between nav bar and outlet (which may be a non-starter).
  2. Add a new MatTabNavOutlet component that wraps the outlet. Pass its instance to MatTabNavBar via an [outlet] input. If [outlet] input is specified, MatTabNavBar has ARIA tab interaction. Otherwise, it has the default ARIA link interaction. Backwards compatible.
  3. Update MatTabGroup to (1) support links and (2) support outlets, and (3) separate the "tablist" and "tabpanel" components. Also fully deprecate MatTabNavBar at this point. A ton of work but maybe the north star.
  4. Do nothing.

If we did 2, we could add the new component / update MatTabNavBar in a fully backwards compatible way. Then we could migrate all g3 usages to the new API. Finally we could remove the logic in MatTabNavBar that changes its behavior based upon whether the [outlet] input is specified, and just make the input required.

@zelliott
Copy link
Collaborator

zelliott commented Dec 6, 2021

@crisbeto, @jelbourn: PTAL at the WIP PR above if you have a sec. It turned out to be pretty easy to implement option 2, and only required 1-2 usage changes in g3. If we do go with 2, would we want to manually migrate all g3 usages to use MatTabNavPanel so that we can remove the logic that defaults to link/navigation semantics if no panel is provided? Or are we comfortable living in a world where MatTabNav can render as either link/navigation or ARIA tabs based upon whether the developer has provided a panel?

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Feb 7, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Accessibility This issue is related to accessibility (a11y) area: material/tabs P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent
Projects
None yet
2 participants