WordPress / gutenberg

The Block Editor project for WordPress and beyond. Plugin is available from the official repository.
https://wordpress.org/gutenberg/
Other
10.3k stars 4.11k forks source link

Tabs with longer strings may trigger horizontal scrolling of the panels they live in #62020

Open afercia opened 3 months ago

afercia commented 3 months ago

Description

See related https://github.com/WordPress/gutenberg/issues/62018

As mentioned in See related https://github.com/WordPress/gutenberg/issues/62018, limited width space and horizontal tabs aren't good friends.

When the 'Show button text labels' preference is enabled and WordPress is set to languages other than English, some tabs may use strings that are way longer than the English ones.

The tabs use a CSS flex layout that doesn't allow flex wrap. The text inside the tabs can wrap to multiple lines but that triggers one more problem, see https://github.com/WordPress/gutenberg/issues/62018

Horizontal scrolling is a problem for usability, readability, and accessibility as some content may be cut-off and not fully readable. Additionally, scrolling in a horizontal direction ro reveal content is a problem for keyboard users. In general, horizontal scrolling should be prevented. Also, the editor doesn't have (yet) a 'scrollable' component that is fully accessible.

Animated GIF to illustrate the horizontal scrolling with 3 tabs in the Inspector panel and WordPress language set to German:

hscrolling german

The same problem can be reproduced with Dutch and Italian, and I guess with more languages:

dutch

italian

Step-by-step reproduction instructions

Screenshots, screen recording, code snippet

No response

Environment info

No response

Please confirm that you have searched existing issues in the repo.

Yes

Please confirm that you have tested with all plugins deactivated except Gutenberg.

Yes

afercia commented 3 months ago

This requires some design feedback first Cc @WordPress/gutenberg-design

I can think of two options:

Three horizontal tabs in a narrow sidebar seem not ideal in the first place.

jasmussen commented 3 months ago

Would it make sense to have a new dedicated label for text-labels-only mode? There are quite a lot of issues related to the feature, perhaps enough that it deserves its own category. I'm not sure that allowing wrapping, or setting best-practice guidelines (since those can be broken by third party consumers) is necessarily the best way to do handle the overflow, and overflow is something you'll see in a slew of places across tabs, block toolbars, popovers, modals on mobile. Would transforming when text doesn't fit be a solution?

afercia commented 2 months ago

To me, the root issue for this case and for similar cases in the editor UI is the usage of fixed heights.

On the web, text is supposed to reflow and re-adapt when the container size changes. I would say it's the beauty of the web. Attempting to design a pixel-perfext design with fixed heights and sizes is often pointles and introduces problems. Any container should allow its content to reflow and adapt.

Instead, I see the trend in the editor is to try to adapt the content to the design. It should really work the opposite way. The design should be built around the content.

It is also worth mentioning that, from an accessibility perspective, any layout should support text-only zoom up to 200% without loss of content or functionality. Fixed heights typically break tet-only zoom.

That's the reason why in core all buttons and form controls have been changed to not use fixed heights and now they can scale with text. The saem principle should be used in core, also for the tabs and any other text container that uses fixed heights,

On the other hand, I'd be totally in favor of using shorter labels. Some labels are visually hidden by default and you realize that are too long only when made visible. However, I'm not in favor of providing pairs of labels with an additional bale for 'show button text labels' because:

jameskoster commented 2 months ago

I think this is an issue with the Tabs component, rather than the 'Show button text labels' feature. It should better handle long labels, and adapt more elegantly to narrow spaces.

This is bad, but can probably be improved significantly with one or two small tweaks:

https://github.com/WordPress/gutenberg/assets/846565/81ab47e5-14fe-4145-af53-f7a2a82e8f58

Options to try:

A hacky mockup:

https://github.com/WordPress/gutenberg/assets/846565/2d6d4b98-1b6c-45d1-b449-c1ee9b34320b

afercia commented 2 months ago

Just noting that horizontal scrolling is never recommended because it isn't a great experience for keyboard users. Also, browsers handle scrollable elements in a different way, see explanation at https://github.com/WordPress/gutenberg/issues/45809

Truncating content could be explored but I don't think it's the best option. Rather, the UI should be designed around content. I'd think all this kind os content manipulation would treat the symptom rather than the actual disease. The root problem is is that a narrow container like a side panel has very limited horizontal space for horizontal tabs.

jameskoster commented 2 months ago

Another option would be to allow tabs to wrap. The current design doesn't particularly lend itself to this though:

tabs

A revised visual treatment which doesn't look so clunky when wrapping could be a solution:

tabs

But obviously this would have a widespread effect and require careful consideration.

ciampo commented 2 months ago

👋 Catching up through Tabs-related conversations to understand if there are any potential blockers that should delay the stabilization of Tabs as-is.

Recently, an improvement to how multi-line tabs text is handled in Tabs was merged recently.

Regarding the issue highlighted in this conversation, I have two short-term proposed fixes:

Tweak Tabs so that the tabs text can break line more easily

Click to show proposed changes ```diff diff --git a/packages/components/src/tabs/stories/index.story.tsx b/packages/components/src/tabs/stories/index.story.tsx index 164b2cbb5e..398f03f74d 100644 --- a/packages/components/src/tabs/stories/index.story.tsx +++ b/packages/components/src/tabs/stories/index.story.tsx @@ -41,9 +41,18 @@ const Template: StoryFn< typeof Tabs > = ( props ) => { return ( - Tab 1 - Tab 2 - Tab 3 + + Tab one has a very very long tab label + withonewordthathasnospacesandcantbebroken + + + Tab two has a very very long tab label + withonewordthathasnospacesandcantbebroken + + + Tab three has a very very long tab label + withonewordthathasnospacesandcantbebroken +

Selected tab: Tab 1

diff --git a/packages/components/src/tabs/styles.ts b/packages/components/src/tabs/styles.ts index d6fb117a30..fca6423b2e 100644 --- a/packages/components/src/tabs/styles.ts +++ b/packages/components/src/tabs/styles.ts @@ -75,6 +75,7 @@ export const Tab = styled( Ariakit.Tab )` margin-left: 0; font-weight: 500; text-align: inherit; + word-break: break-word; &[aria-disabled='true'] { cursor: default; ```
Before (trunk) After (with the above diff applied)
Screenshot 2024-07-09 at 15 22 32 Screenshot 2024-07-09 at 15 22 11

Use Truncate and compose it with Tabs

Click to show proposed changes ```diff diff --git a/packages/components/src/tabs/stories/index.story.tsx b/packages/components/src/tabs/stories/index.story.tsx index 164b2cbb5e..32cb3917d6 100644 --- a/packages/components/src/tabs/stories/index.story.tsx +++ b/packages/components/src/tabs/stories/index.story.tsx @@ -16,6 +16,7 @@ import Tabs from '..'; import { Slot, Fill, Provider as SlotFillProvider } from '../../slot-fill'; import DropdownMenu from '../../dropdown-menu'; import Button from '../../button'; +import { Truncate } from '../../truncate'; const meta: Meta< typeof Tabs > = { title: 'Components (Experimental)/Tabs', @@ -41,9 +42,24 @@ const Template: StoryFn< typeof Tabs > = ( props ) => { return ( - Tab 1 - Tab 2 - Tab 3 + + + Tab one has a very very long tab label + withonewordthathasnospacesandcantbebroken + + + + + Tab two has a very very long tab label + withonewordthathasnospacesandcantbebroken + + + + + Tab three has a very very long tab label + withonewordthathasnospacesandcantbebroken + +

Selected tab: Tab 1

```
Before (trunk) After (with the above diff applied)
Screenshot 2024-07-09 at 15 22 32 Screenshot 2024-07-09 at 15 29 09

Any thoughts?

cc @WordPress/gutenberg-components

DaniGuardiola commented 2 months ago

@ciampo I think I favor option 1 now that the tab height is fluid, because no information is lost (from a visual standpoint). With option 2, we'd need to add some sort of "tooltip if overflow" mechanism which is notably hard to implement properly without negatively affecting the experience of a mouse user (I have done this before, happy to elaborate on why if there's still support for that option).

DaniGuardiola commented 2 months ago

Also eager to read @jasmussen's and @WordPress/gutenberg-design thoughts on it, I see it's been added to the design priorities so maybe they'll think of an alternative solution. I would add that overflowing scrollable tabs is not necessarily a bad UX if implemented properly IMO, but it's tricky and comes with challenges in multiple dimensions, like discoverability and interaction in different mediums.

jasmussen commented 2 months ago

My main read is that this is a forcing function to use the componentry carefully and towards best practices. Even if we allow wrapping the text inside a tab on two lines, arguably it's an argument for either seeking out a shorter label, or use two tabs in the design instead, or even something else. We can improve how the componentry handles this, of course we should, but it we can never prevent a consumer from using the components in a way that breaks best practices.

ciampo commented 2 months ago

Agreed!

I'm happy to push a PR to implement option 1, if folks think that it would be a small improvement to the component anyway.

tyxla commented 2 months ago

I think option 1 is a good compromise. If I were designing tab usage within my plugin, I'd definitely be careful to avoid multiline tabs, or at least keep multi-line tab text for all tabs.

jameskoster commented 2 months ago

@ciampo should we use hyphens instead of word-break?

ciampo commented 2 months ago

@jameskoster TIL that hyphens is now available in all evergreen browsers! Opened #63337 as discussed.

afercia commented 2 months ago

Thanks everyone for looking into this and for your thoughts. Here's 4 screenshots to try to summarize:

before

  1. Before https://github.com/WordPress/gutenberg/pull/62027 with no fluid height.
  2. After https://github.com/WordPress/gutenberg/pull/62027 with fluid height. Still, long unbreakable words would trigger horizontal scrolling when tabs are placed in a narrow container.
  3. With word-break: break-word;. This would solve the horizontal scrolling issue but words would be split incorrectly, not respecting syllables.
  4. With hyphens: auto;. This looks better, at least words are split correctly and are more readable.

I'd agree hyphens: auto; seems the most reasonable and less invasive option. It is still a little opinionated though.

If I were designing tab usage within my plugin, I'd definitely be careful to avoid multiline tabs

That's what I would do as well as a plugin author. However, translations may provide longer strings, thus making my efforts vain. Overall, I'd think that making sure the tabs content is always fully visible is a responsibility of the component so that hyphens: auto; is probably the most acceptable option.

However, regarding the specific case in the inspector panel, I'd like to note that any fix in the component is curing the symptom rather than the cause. The root problem is that placing 3 horizontal tabs in a panel with a narrow width isn't the best design choice in the first place.

ciampo commented 2 months ago

With https://github.com/WordPress/gutenberg/pull/63337 merged, this issue shouldn't really present itself — feel free to close it, or to keep it open if you'd rather look for a more optimal solution.

jameskoster commented 1 month ago

I think the tab component could still use an update to better handle the many-tabs-in-narrow-container scenario.

This component could feature heavily in admin redesign work (https://github.com/WordPress/gutenberg/issues/53322). If so, it's possible that longer tab rows could be employed, and these will need to scale elegantly down to mobile.

As I noted in https://github.com/WordPress/gutenberg/issues/62020#issuecomment-2182740050 the current design doesn't lend itself very well to wrapping. Should we open a new issue to explore this problem?

Screenshot 2024-07-29 at 09 46 44
ciampo commented 1 month ago

I think so, this sounds like a different topic: should the TabList allow for scrolling? If yes, should we make any changes to the Tabs component (ie. add props)? Should we change any aspects of the current design? How does work when the tabs are oriented vertically?

Let's open a separate issue 👌

DaniGuardiola commented 1 month ago

I think that at the very least, Tabs should handle overflow nicely, if only to not have a totally broken UX (including considerations like the indicator animation, which might not account for scroll - haven't checked).

I wanted to add that https://github.com/WordPress/gutenberg/pull/61974 has the potential to mitigate this issue for a good amount of instances (in sidebars) for some localizations, since it allows a better management of space than the current balanced layout.

jameskoster commented 1 month ago

I opened https://github.com/WordPress/gutenberg/issues/64093.