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

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

Open
afercia opened this issue May 27, 2024 · 20 comments
Labels
CSS Styling Related to editor and front end styles, CSS-specific issues. [Feature] Show button text labels A preference in the Post and Site Editor that makes buttons show text instead of icons [Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). Needs Design Feedback Needs general design feedback. [Package] Components /packages/components [Type] Bug An existing feature does not function as intended

Comments

@afercia
Copy link
Contributor

afercia commented May 27, 2024

Description

See related #62018

As mentioned in See related #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 #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

  • Switch WordPress language to German, Dutch, or Italian.
  • Go to the post editor and add a navigation block.
  • Note: the navigation block i just an example. This problem occurs wherever there are two or three tabs in a narrow panel and the tabs text contaisn long, unbreakable, words..
  • Go to Options > Preferences > Accessibility, and enable the 'Show button text labels' preference.
  • With the navigation block selected, observe the block inspector panel.
  • Move your mouse horizontally over the Inspector panel and observe the panel scrolls horizontally.
  • Alternatively, tab through the tabs.

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 afercia added [Type] Bug An existing feature does not function as intended [Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). Needs Design Feedback Needs general design feedback. [Package] Components /packages/components CSS Styling Related to editor and front end styles, CSS-specific issues. [Feature] Show button text labels A preference in the Post and Site Editor that makes buttons show text instead of icons labels May 27, 2024
@afercia
Copy link
Contributor Author

afercia commented Jun 10, 2024

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

I can think of two options:

  • Either allow the tabs flex layout to wrap to a new line
  • Or establish strict guidelines for 1) the amount of tabs in a narrow sidebar 2) the length of the tabs translatable strings

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

@jasmussen
Copy link
Contributor

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
Copy link
Contributor Author

afercia commented Jun 18, 2024

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:

  • The editor should provide equivalent information for all users, regardless of the editor preferences users set, device and assistive technology in use.
  • It would double translators work.
    See https://core.trac.wordpress.org/changeset/46243

@jameskoster
Copy link
Contributor

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:

tabs.mp4

Options to try:

  • Horizontal scrolling (of only the tab row container)
  • Truncate extremely long labels (with tooltip)

A hacky mockup:

tabs.mp4

@afercia
Copy link
Contributor Author

afercia commented Jun 20, 2024

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 #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
Copy link
Contributor

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
Copy link
Contributor

ciampo commented Jul 9, 2024

👋 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 --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 (
 		<Tabs { ...props }>
 			<Tabs.TabList>
-				<Tabs.Tab tabId="tab1">Tab 1</Tabs.Tab>
-				<Tabs.Tab tabId="tab2">Tab 2</Tabs.Tab>
-				<Tabs.Tab tabId="tab3">Tab 3</Tabs.Tab>
+				<Tabs.Tab tabId="tab1">
+					Tab one has a very very long tab label
+					withonewordthathasnospacesandcantbebroken
+				</Tabs.Tab>
+				<Tabs.Tab tabId="tab2">
+					Tab two has a very very long tab label
+					withonewordthathasnospacesandcantbebroken
+				</Tabs.Tab>
+				<Tabs.Tab tabId="tab3">
+					Tab three has a very very long tab label
+					withonewordthathasnospacesandcantbebroken
+				</Tabs.Tab>
 			</Tabs.TabList>
 			<Tabs.TabPanel tabId="tab1">
 				<p>Selected tab: Tab 1</p>
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 --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 (
 		<Tabs { ...props }>
 			<Tabs.TabList>
-				<Tabs.Tab tabId="tab1">Tab 1</Tabs.Tab>
-				<Tabs.Tab tabId="tab2">Tab 2</Tabs.Tab>
-				<Tabs.Tab tabId="tab3">Tab 3</Tabs.Tab>
+				<Tabs.Tab tabId="tab1">
+					<Truncate numberOfLines={ 1 }>
+						Tab one has a very very long tab label
+						withonewordthathasnospacesandcantbebroken
+					</Truncate>
+				</Tabs.Tab>
+				<Tabs.Tab tabId="tab2">
+					<Truncate numberOfLines={ 1 }>
+						Tab two has a very very long tab label
+						withonewordthathasnospacesandcantbebroken
+					</Truncate>
+				</Tabs.Tab>
+				<Tabs.Tab tabId="tab3">
+					<Truncate numberOfLines={ 1 }>
+						Tab three has a very very long tab label
+						withonewordthathasnospacesandcantbebroken
+					</Truncate>
+				</Tabs.Tab>
 			</Tabs.TabList>
 			<Tabs.TabPanel tabId="tab1">
 				<p>Selected tab: Tab 1</p>

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
Copy link
Contributor

@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
Copy link
Contributor

DaniGuardiola commented Jul 9, 2024

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
Copy link
Contributor

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
Copy link
Contributor

ciampo commented Jul 9, 2024

Agreed!

  • Option 1 would definitely be less opinionated (and it's also my favourite between the two)
  • Scrolling tabs introduce a whole new series of challenges that are tricky to implement well
  • I also agree with Joen that this is also a symptom that we can do better at the app level

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
Copy link
Member

tyxla commented Jul 9, 2024

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
Copy link
Contributor

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

@ciampo
Copy link
Contributor

ciampo commented Jul 10, 2024

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

@afercia
Copy link
Contributor Author

afercia commented Jul 10, 2024

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

before

  1. Before Make Tabs have a fluid height #62027 with no fluid height.
  2. After Make Tabs have a fluid height #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
Copy link
Contributor

ciampo commented Jul 10, 2024

With #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
Copy link
Contributor

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 (#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 #62020 (comment) 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
Copy link
Contributor

ciampo commented Jul 29, 2024

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
Copy link
Contributor

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 #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
Copy link
Contributor

I opened #64093.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CSS Styling Related to editor and front end styles, CSS-specific issues. [Feature] Show button text labels A preference in the Post and Site Editor that makes buttons show text instead of icons [Focus] Accessibility (a11y) Changes that impact accessibility and need corresponding review (e.g. markup changes). Needs Design Feedback Needs general design feedback. [Package] Components /packages/components [Type] Bug An existing feature does not function as intended
Projects
Status: Next
Development

No branches or pull requests

6 participants