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

Improve display of many tabs in narrow containers #64093

Open
jameskoster opened this issue Jul 30, 2024 · 32 comments
Open

Improve display of many tabs in narrow containers #64093

jameskoster opened this issue Jul 30, 2024 · 32 comments
Labels
[Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). Needs Dev Ready for, and needs developer efforts [Package] Components /packages/components [Type] Bug An existing feature does not function as intended [Type] Enhancement A suggestion for improvement.

Comments

@jameskoster
Copy link
Contributor

jameskoster commented Jul 30, 2024

If an admin page were to use an instance of Tabs containing many tabs, here's how that would scale down to narrow viewports (e.g. Mobile):

Screenshot 2024-07-30 at 12 33 36

Clearly this doesn't work very well; half the tabs would be offscreen and totally inaccessible. Let's work out how Tabs should handle these situations. Obvious solutions could be wrapping, or horizontal scrolling. Let's explore.

Wrapping Scrolling
Screenshot 2024-07-30 at 12 35 57 scroll

Edit: Based on the discussion in this issue, scrolling seems the approach to try first.

@jameskoster jameskoster added [Type] Enhancement A suggestion for improvement. Needs Design Needs design efforts. [Package] Components /packages/components labels Jul 30, 2024
@jameskoster jameskoster added the [Type] Bug An existing feature does not function as intended label Jul 30, 2024
@jameskoster
Copy link
Contributor Author

Noticed this is already an issue in the Style Book:

Screenshot 2024-07-30 at 13 12 20

@ciampo
Copy link
Contributor

ciampo commented Jul 30, 2024

Obvious solutions could be wrapping, or horizontal scrolling

Do you think we'd even need both to be possible options?

We could expose a prop (name TBD, but something like overflow) that takes three values:

  • default: behaves as it does currently;
  • wrap: wraps tabs to new rows
  • scroll: allows the parent tablist to scroll

@jameskoster
Copy link
Contributor Author

Yup, that could be the way forward.

default could utilise the "Fill" approach we've been discussing in #61974 (comment).

@jameskoster
Copy link
Contributor Author

Probably separate, but if we include wrap as a layout option then there may also be a case to revisit the hover/active state design. This looks a little awkward to me, and when there are multiple rows there may be cases where it's not clear which item the indicator belongs to:

Screenshot 2024-07-30 at 14 54 58

The animation might be a little strange too.

I wonder if we really need wrap. Come to think of it I'm struggling to think of examples where it would be preferable to horizontal scrolling.

@jameskoster
Copy link
Contributor Author

Another option could be a dynamic overflow menu, but I suppose that would be very complex...

overflow

@ciampo
Copy link
Contributor

ciampo commented Jul 30, 2024

I wonder if we really need wrap

Probably not if we're happy with scrolling tablists.

default could utilise the "Fill" approach we've been discussing in #61974 (comment).

Looking at that conversation, it seems like we may still need both the "left aligned" and "width balanced" (with centered text) version, so that may actually warrant more thinking in terms of what variants we want to expose.

  • overflow behavior:
    • allow scrolling;
    • do not allow scrolling
  • tabs "growth":
    • split all available space in the tablist evenly and center text ("balanced")
    • keep tabs as narrow as their contents, keep left aligned

The "balanced" approach doesn't make much sense if the content is overflowing and scrolling, IMO — so we'd need to defined exactly what combinations are allowed and how we want to expose them.

Another option could be a dynamic overflow menu, but I suppose that would be very complex...

I'm skeptical about that approach, since collapsing tabs in the dropdown menu would make them hard to discover, and it would likely be hard to comply with the WAI-ARIA Tabs pattern.

@jameskoster
Copy link
Contributor Author

There may be a third option for tab growth; balanced with left-aligned text. Like we find in the Inserter:

Screenshot 2024-07-30 at 17 37 35

I suppose the outcome of #61974 will dictate how we proceed here.

@DaniGuardiola
Copy link
Contributor

DaniGuardiola commented Aug 5, 2024

My two cents:

  • Wrapping is hard to implement for a few reasons: it comes with some general CSS layout challenges, doesn't play well with vertical orientation, and the indicator line is now not at the bottom of the component but floating around instead.
  • When defaulting to "non-balanced" layouts (as proposed for sidebars in Try: Improved tabbed sidebar styles #61974), it's harder for tabs to overflow as text adapts to the available space more easily, making this concern less pressing. That said, I believe it's possible to go with a "best effort fill" approach, where tabs get progressively more squished until there is no space left and then start overflowing with scroll as you reduce the size of the tab container.
  • I personally strongly prefer tab labels to be centered if there's a "fill" layout. The "fill" but left-aligned layout looks instantly wrong to me (the indicator accentuates this effect), which is the reason I started Try: Improved tabbed sidebar styles #61974 originally. Maybe that's just me though!
  • Scrolling is much easier to implement, mobile-friendly, and (I think) more familiar to users in the event that it happens. There are ways to indicate that there's overflowing content to be accessed if that's a concern, including visual "arrow" buttons that are only shown where there's overflowing tabs.
  • Wrapping comes with UX problems imo, like making it hard to relate the active tab with the content, or giving the impression of nested levels of navigation (e.g. two rows of tabs might seem like two different page-level and sub-page-level tab lists).
  • Scroll feels naturally simpler to me.

@jameskoster
Copy link
Contributor Author

Scrolling works for me, so long as it's obvious. Certainly worth a try in a PR imo.

@jameskoster jameskoster added Needs Dev Ready for, and needs developer efforts and removed Needs Design Needs design efforts. labels Aug 6, 2024
@DaniGuardiola
Copy link
Contributor

@WordPress/gutenberg-design scrolling implementation: #64371

cc @jameskoster @ciampo

@afercia afercia added the [Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). label Sep 2, 2024
@afercia
Copy link
Contributor

afercia commented Sep 2, 2024

Based on the discussion in this issue, scrolling seems the approach to try first.

Horizontal scrolling is an accessibility barrier for many users. It is not strictly prohibited, but is it discouraged. Pinging @joedolson for more insights as I think he knows more than me on this topic.

A couple more important considerations:

  • To me, this seems to cure more the symptom rather than the actual disease. By their own nature, horizontal tabs potentially require a good amount of horizontal space. A design that wants to place many horizontal tabs in a narrow space like a sidebar is a design that is not ideal in the first place.
  • It is worth reminding that browsers treat scrollable div elements (or other elements) differently. Most notably, Firefox makes scrollable elements focusable. It makes them focusable only when there is an actual content overflow, so the 'focusability' is actually dynamic. To make scrollable elements accessible and provide a consistent experience across browsers, the scrollable element would need some special treatment, which is a little overkill to me. See the changes made to the mocal dialog content container to detect scrollable content on Fix constrained tabbing failures with Safari and Firefox #47426 and see the general issue at Improve the Scrollable component accessibility #45809

@ciampo
Copy link
Contributor

ciampo commented Sep 2, 2024

@afercia

To me, this seems to cure more the symptom rather than the actual disease. By their own nature, horizontal tabs potentially require a good amount of horizontal space. A design that wants to place many horizontal tabs in a narrow space like a sidebar is a design that is not ideal in the first place.

This is definitely a good point, although here the conversation is more general than the editor sidebar. We're discussing how Tabs may react to any situation in which, for whatever reason, the tabs would overflow their container (see original issue description). I agree that it's not ideal, but at the same time, it's good IMO to have a way to deal with this scenario when it happens.

  • It is worth reminding that browsers treat scrollable div elements (or other elements) differently. Most notably, Firefox makes scrollable elements focusable. It makes them focusable only when there is an actual content overflow, so the 'focusability' is actually dynamic. To make scrollable elements accessible and provide a consistent experience across browsers, the scrollable element would need some special treatment, which is a little overkill to me.

What are the actual implications for this specific scenario ? The only potential conflict that I see is that using arrow keys may pose a conflict, since arrow keys would be used for both horizontal scrolling and for moving the active composite item (the tab)


I'm also going to add that one of the recommended alternatives for when tabs overflow is to switch them to be vertically stacked, similarly an accordion interface — example — although I'm not sure if this would work well for the use cases that we envision.

@jameskoster
Copy link
Contributor Author

Even in a container of adequate width horizontal tabs will need to scale down to mobile. I agree that responsible usage should be encouraged, but making components adaptive to different environments also seems beneficial.

Wrapping is the only alternative I can think of, but that would likely require a different (maybe grid-based) design, e.g.:

Screenshot 2024-09-02 at 16 21 42

But then we run into issues around wrapping the labels, and it's not clear how keyboard interaction would work in such a display.

It's not perfect, but horizontal scroll does seem to be the simplest solution.

@joedolson
Copy link
Contributor

I agree that we need to have some mechanism to react to a Tab component exceeding the width of its container; but adding horizontal scrolling is, in my opinion, just choosing not to react to the width. It's leaving the component unchanged, and requiring the user to accept that parts of it are hidden.

There isn't a WCAG guideline violation as long as only one direction of scrolling is required; but it's not a great user interface - it makes discoverability and usability more difficult.

Mouse operation of small scrollable areas can be difficult; the scrollbar is a difficult target to hit, and many users don't know the keyboard trigger to change a scroll wheel to handle horizontal scrolling. Keyboard operation should be mostly automatic, since the focused item should move into view when it receives focus (required under WCAG 2.4.11). However, there is a potential keyboard conflict in arrow key behavior as @ciampo observed; I'd consider that a significant problem with that solution, more significant than the potential ambiguity of how keyboard navigation would work in the grid view.

If the arrow key no longer worked for tab navigation (this is hypothetical, with no interface to test this on) because it is needed for scrolling, then there would be a sudden and unexpected change of interface behavior for any tab component with too many tabs. There is no necessary keyboard change in the grid view; the only potential change would be to add support for up and down arrows, but that would be entirely optional.

My preference would be to go to the grid view, and modify the design to accommodate that.

@afercia
Copy link
Contributor

afercia commented Sep 3, 2024

Some research always helps clarifying ideas and exploring approaches from other design systems. It is even more valuable when the design system is used and tested on a large scale or when the source is of high quality.

Nielsen Norman Group

In Tabs, Used Right, the Nielsen Norman Group summarize a few principles for best tabs usage. The relevant ones for our case are:

When the number of tabs overflows the tab list, the tab bar often becomes a carousel. As a result, the hidden tabs become less discoverable, and the interaction cost needed to access them increases, as users need to manipulate secondary controls to reveal those tabs. The fewer tabs, the better.\

For smaller viewports, they suggest to use accordions:

Accordions are another effective method for collapsing content. Accordions are particularly useful on mobile devices, where they work better than tabs due to the limited screen space.

Alternatively, they do mention tabs like a carousel with buttons to scroll horizontally. However, the placement and order of the buttons combined with the expected arrow navigation on the tabs would make keyboard interaction less than ideal.

One very important principle they state:

Use Only One Row of Tabs

The reason for this is that when wrapping tabs in multiple lines, whether it's a grid or just tabs reflowing to multiple lines, the visual connection between the selected Tab and its associated panel may be entirely lost, thus defeating the purpose of using a tabbed interface.

As such, wrapping tabs doesn't seem to me the best option. As an example, I remember Windows used the wrapping tabs pattern and, to keep the visual connection between the selected tab and its panel, they used to 'swap on the fly' the order of the tab rows. Besides the unexpected change of the tabs order, I'd argue that was a terrible UI. Animated GIF for history:

xp tabs

Adobe’s design system: Spectrum

To handle tab overflow, they suggest to switch the tabs to a dropdown menu. Animated GIF to illustrate:

spectrum tabs

I find this pattern interesting, especially if the expected arrows navigation is kept to 1) open the dropdown 2) navigate through the tabs-menu-items.

Material Design 3

Lastly, it's worth mentioning Material Design even though it's important to remind everyone that Material was built on a mobile-first sensibility, considering its original purpose was for designing Android apps. As such, any pattern from Material should be considered with care as it may not be ideal for web design as a device-agnostic, universal and accessible approach.

Their Scrollable tabs are clearly designed for touch interfaces. The docs explicitly mention They are best used for browsing on touch interfaces.

@jameskoster
Copy link
Contributor Author

jameskoster commented Sep 3, 2024

they suggest to switch the tabs to a dropdown menu

A potential drawback with this approach is how frequently the switch might occur. The dropdown is quite a big downgrade in terms of usability due to how tedious it would make navigating between tabs.

A settings screen like this one from Woo could end up in dropdown orientation the majority of the time for many users.

Screenshot 2024-09-03 at 11 58 48

I know Marco had some reservations, but did you see the comment above about dynamically switching to a dropdown only when overflow occurs? Could that be a middle-ground option?

@afercia
Copy link
Contributor

afercia commented Sep 3, 2024

A settings screen like this one from Woo could end up in dropdown orientation the majority of the time for many users

A mixed approach could be something to consider for example 'only when overflow occurs' as in: show as many horizontal tabs as possible and group the last ones (the ones that overflow) in a dropdown. It would be interesting to experiment if arrows navigation would work well with such a pattern.

@DaniGuardiola
Copy link
Contributor

One important point to make is that, as long as the overflow is clearly indicated (e.g. #64371 (comment)), keeping the tabs as they are with overflow is the superior UX for screen reader and keyboard users.

  • Screen readers will still be able to detect all tabs and interact with them as normally, it will be the exact same experience as overflow does not affect the tree.
  • Keyboard users interact in the exact same way: focus the tabs, then use the arrow keys to navigate them. Tabs are automatically scrolled into view.

Mouse users need an extra interaction: use the scrollbar OR click the overflow arrows (if we end up going with that UX). That seems like a decent compromise, and in fact it maximizes the information shown to users (all tabs that fit in the container) vs. switching to dropdown (only the active tab). This is also an established pattern in mobile devices, where scrolling with touch is expected (and these are the mediums where this case will happen more often due to smaller screen sizes). It feels natural to scroll overflowing tabs in mobile devices.

We do need to get the overflow indicators right, that's critical. But it seems to me like that's the only significant challenge. Overflow is the option with less cognitive load from all suggestions I've seen in this thread, by far (IMO). It's also consistent between all sizes, and the easiest to interact with in all input methods. And they ALWAYS look like what they are: tabs.

@DaniGuardiola
Copy link
Contributor

@joedolson

requiring the user to accept that parts of it are hidden

This is also the case with other alternatives like a dropdown menu. But I do not think this is critical, as long as the hidden content is clearly indicated and easy to access (e.g. #64371 (comment)).

Mouse operation of small scrollable areas can be difficult; the scrollbar is a difficult target to hit, and many users don't know the keyboard trigger to change a scroll wheel to handle horizontal scrolling.

That is true, but I think if we go with the arrow indicators of overflow, those can be buttons that perform the scroll which solves the issue.

there is a potential keyboard conflict in arrow key behavior

This just doesn't happen. There is no conflict: tabs are navigated with arrows and they scroll into view if necessary. See #64371 where this is already implemented.

If the arrow key no longer worked for tab navigation (this is hypothetical, with no interface to test this on) because it is needed for scrolling, then there would be a sudden and unexpected change of interface behavior for any tab component with too many tabs.

You can test it, and there's no change. See the PR I linked.

@afercia
Copy link
Contributor

afercia commented Sep 5, 2024

@DaniGuardiola

keeping the tabs as they are with overflow is the superior UX for screen reader and keyboard users.

I'm afraid this is a bit arguable. First, as I explained in #64371 (comment) browsers treat scrollable elements inconsistently and that would be a problem to fix to provide a consistent, usable and accessible experience.

it will be the exact same experience as overflow does not affect the tree.

I does affect the tree, as Firefox makes a scrollable element focusable.

Keyboard users interact in the exact same way:

I'm afraid this isn't correct, because browsers treat scrollable elements in a different way.

Overflow is the option with less cognitive load from all suggestions I've seen in this thread

as you correctly mention, this is your personal opinion and it's totally respectable but i disagree with it. Overflow actually hides content and it is inherently confusing for users with cognitive impairments, non-tech savvy users etc. Usability and accessibility aren't just about keyboard and screen readers. There's a lot to take into account and in my opinion horizontqal scrolling introduces more problems than it solves.

@jameskoster
Copy link
Contributor Author

It would be interesting to experiment if arrows navigation would work well with such a pattern.

@afercia How would you expect keyboard interaction to work when you reach the dropdown? I assume the dropdown should auto-open and that the "More..." item shouldn't be focussable itself, else the expect pattern for navigating tabs is broken. But perhaps that's wrong? For navigating the dropdown; Up/down arrows, left/right, both?

It's only Figma but I made a prototype here to try it the options. Video:

tabs.mp4

@ciampo
Copy link
Contributor

ciampo commented Sep 5, 2024

show as many horizontal tabs as possible and group the last ones (the ones that overflo) in a dropdown. It would be interesting to experiment if arrows navigation would work well with such a pattern.

I don't understand how this approach would be acceptable, in terms of accessibility and content discovery. In my opinion, it's worse than overlow+scrolling, since the items in the dropdown won't be exposed to the user (and assistive technology) until the dropdown is open.

And even in terms of cognitive overload, we'd be mixing two different UX patterns (tabs + dropdown menu) instead of just tabs.

@afercia
Copy link
Contributor

afercia commented Sep 6, 2024

How would you expect keyboard interaction to work when you reach the dropdown? I assume the dropdown should auto-open and that the "More..." item shouldn't be focussable itself,

@jameskoster I wouldn't expect the dropdown toggle to be labeled 'More'. Rather, like in the GIF that illustrates the Adobe pattern on #64093 (comment), the dropdown shows the selected tab label.

Worth reminding the Tabs pattern can be either with automatic activation of the tabpanel or with Manual activation as in:

  • Automatic: when users navigate with arrows through the tabs, the tabpanel is shown as soon as a new tab gets focus.
  • Manual: navigating with arrows only selects the tab. Pressing Enter or Spacebar shows the tabpanel.

The automatic pattern would not work with the tabs rearranged in a dropdown. Instead maybe it's worth exploring the manual pattern where:

  • Arrows select the current tab shown in the dropdown and open the dropdown.
  • Users can navigate the tabs within the dropdown with arrows keys, as they would normally do.
  • Enter or Spacebar opens the selected tabpanel.
  • The selected tabs becomes the one shown in the dropdown toggle

Basically, what I have in mind is a pattern where the tabs are still tabs. Cc @ciampo
They are just rearranged within a 'visual' dropdown but the semantics and keyboard interaction would still be the one of the Tabs pattern.

The limitations I can see off the top o fmy head is:

  • Automatic activation can't be an option in this case.
  • The Home and End keys, which normally move focus to the first and last tabs, wouldn't work well because the End key should open the dropdown and focus the last tab, which would likely be unexpected.
  • Looping with arrow keys wouldn't work well for the same reason.

Of course, this is just an idea that should be explored and tested and I'm not pretending it's the 'right' or best option. However, instead of resorting to CSS-based solutions and actually hiding content in a scrollable div with all the accessibility concerns mentioned earlier, I'd encourage to rearrange the tabs into an alternative UI for small viewports that is more clear, predictable, and more accessible than a scrollable div.

@jameskoster
Copy link
Contributor Author

There doesn't seem to be a clear solution here; they all have drawbacks 😖

What if we added scrolling initially then revisit with a more comprehensive solution later? I appreciate it's not ideal, but it would be good to fix the bugged behavior.

@afercia
Copy link
Contributor

afercia commented Sep 9, 2024

What if we added scrolling initially then revisit with a more comprehensive solution later?

I'm not sure introducing a temporary workaround that is clearly not-ideal would be the best option. In my experience with WordPress, once the momentum is gone then ti's hard to find time and opportunity to go focus back on an issue and make things better.

@DaniGuardiola
Copy link
Contributor

DaniGuardiola commented Sep 9, 2024

Currently, it's broken.

I unfortunately don't have much more bandwidth to explore this further on the implementation side right now, so let's default to something that is not broken now instead of something that will be perfect in some uncertain future where I (or someone else) can revisit.

Don't get me wrong, I'd love it if I could just spend more time now to refine this, but that's simply not the case and shipping a broken experience to users is not an option, I hope you can understand @afercia. Fully appreciate your contributions here.

@jameskoster
Copy link
Contributor Author

Yes it would be nice to fix the bug first and foremost. This is not great to say the least:

Screenshot 2024-09-09 at 13 13 20

@afercia
Copy link
Contributor

afercia commented Sep 10, 2024

@DaniGuardiola @jameskoster I greatly appreciate all the effort put in this exploration. However, two experienced accessibility specialists and long time contributors to WordPress, namely @joedolson and I, are kindly asking you to not implement scrolling as it would introduce more harms than good.

We explained why and detailed the underlying problems. We proposed alternative solutions in a proactive way. As such, I'd greatly appreciate to not see a less than ideal approach being forced against important usability abnd accessibility concerns. Scrolling is not a solution. Thanks.

@jameskoster
Copy link
Contributor Author

We proposed alternative solutions in a proactive way.

Do you mean the overflow menu? Are the limitations you outlined not a concern there?

I'm a little bit concerned about the interaction you proposed for the last visible tab and menu. Specifically how the tab label should reflect the chosen item in the dropdown. What if the dropdown contains a really long tab label which – when selected – means that the parent tab (the permanently visible one) becomes too long and overflows? I'm struggling to picture how that works, wouldn't it be confusing?

@afercia
Copy link
Contributor

afercia commented Sep 11, 2024

What if the dropdown contains a really long tab label which – when selected – means that the parent tab (the permanently visible one) becomes too long and overflows

Good point. I'm not pretending to state that the alternative proposal are perfect. However, scrolling is still a no-go to me.
Recently, many UIs in the editor are using truncation to make content fit in a layout. Thad could be an option but, to me, it would be less than ideal. Truncation is not a content strategy. I would like to stress again that design should be crafted around content, not the other way around. Truncating text, shortening labels, using icons only to remove text aren't good ways to make an UI more understandable. They only make content 'fit' in a design but when that happens I would argue the design has some problems in the first place.

WordPress is translated in many languages, plugins can extend the UI (even though the editor is a little less extensible than core) in many ways. Basically we can never predict the length of content, labels, descriptions etc. The whole idea of a 'pixel-perfect' design that is always ideal with any content is illusory because of translations, extensibility etc. Some patterns used in the editor are more problematic than others because of the varyingm unpredictable, length of content for example:

  • Horizontal tabs in a narrow panel
  • Grid layouts in a narrow panel
  • Horizontally aligned buttons in a narrow panel

Specifically to horizontal tabs, a very long label would be problematic also when there is enough space to show all the tabs, right? Example screenshot:

Screenshot 2024-09-11 at 08 58 27

Guidelines may help. More importantly, designers should accept the fact that they should not use horizontal tabs in a very narrow spot because horizontal tabs, by their own nature, require some large horizontal space.

How to mitigate:

  • We recently made tabs have a fluid height. This allows longer label to wrap to multiple lines.
  • We can detect the width of the container.
  • We know the amount of tabs.
  • We can make a decision on the min-width and max-width of the tabs, for example the tabs in the ARIA authoring practices example do use a percentage max-width.
  • The tabs grouped in the dropdown should use the above max-width.
  • The component should detect the width of the wider tab in the dropdown, which can't exeed the above max-width anyways.
  • Based on that, the visible 'tab-label' of the dropdown should use the width of the largest tab in the dropdown.

@jameskoster
Copy link
Contributor Author

designers should accept the fact that they should not use horizontal tabs in a very narrow spot because horizontal tabs, by their own nature, require some large horizontal space.

Wouldn't this imply that horizontal tabs are a fundamentally impractical design pattern? Browsers can be resized, mobile exists... it's inevitable they will render in narrow spots at one time or another.

Guidelines can help, but we cannot be fully responsible for inappropriate use by third parties. When that occurs it is surely better for the component to function (even imperfectly) than to break?

@DaniGuardiola
Copy link
Contributor

@afercia appreciate your comments, see my response: #64371 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). Needs Dev Ready for, and needs developer efforts [Package] Components /packages/components [Type] Bug An existing feature does not function as intended [Type] Enhancement A suggestion for improvement.
Projects
Status: In Dev
Development

No branches or pull requests

5 participants