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

Allow toolbar segments to collapse (responsive toolbar) #9075

Closed
jasmussen opened this issue Aug 17, 2018 · 26 comments · Fixed by #9687
Closed

Allow toolbar segments to collapse (responsive toolbar) #9075

jasmussen opened this issue Aug 17, 2018 · 26 comments · Fixed by #9687
Labels
[Type] Enhancement A suggestion for improvement.

Comments

@jasmussen
Copy link
Contributor

jasmussen commented Aug 17, 2018

When blocks grow thin, whether shown on mobile or in tight nested contexts, the block toolbar currently overflows the boundaries of the block itself. It is not as responsive as it should be.

screen shot 2018-08-17 at 11 10 26

Let's try and mitigate that, by allowing sections of the toolbar to collapse.

When there's space, show everything:

wide

When space becomes a premium, collapse sections into single icons with dropdowns:

thin

thin w popout

Let's start by doing this for alignments (both decorative and text alignment).

The rules of the block toolbar is that they contain, in order:

However you'd never see both the Decorative alignments and text-alignments/inline formatting together. So if we implemented collapsing for all sections, this would be the minimum size of the toolbar:

screen shot 2018-08-17 at 11 02 53

Note that this uses a new icon for formatting — we'd want to discuss that icon first. But this would be an extreme version of toolbar-section-collapsing.

We could look at employing https://github.com/marcj/css-element-queries to help with this.

@chrisvanpatten
Copy link
Contributor

I love this idea! From a code perspective, this could be an additional option on <Toolbar />, allowing you to define the icon that should display as the "collapsed" icon. That could be a generic icon representing all the sub-icons (like your formatting controls example), or one of the selected options (like the alignment controls).

@ZebulanStanphill
Copy link
Member

This is a great idea! It seems like the best way to handle toolbars in nested contexts like columns and in cases where a custom block has a lot of inline actions. It would also be helpful in situations where plugins extend the core blocks to have more options in the toolbar like text color and super/subscript formatting tools.

@youknowriad
Copy link
Contributor

Technically speaking, I'm not certain if this is possible at the moment. How would you decide to trigger the collapsed variation for a Toolbar? How do you choose which Toolbar to trigger first? Even if you come up with a rule like "Trigger the toolbar on the left first", the way these toolbars are added to the block toolbar at the moment (using Slots), doesn't allow for such a behavior to be built: You can't pass an extra prop for a specific toolbar, because I'm assuming the computation of the available space is DOM-related and achieved at the EditorToolbar level.

The only "possible" alternative I can think of is to avoid "smart toolbars" and just trigger the collapsed version of all toolbars on a given breakpoint. It's less ideal, I know but technically speaking the smart behavior is not possible at the moment.

@jasmussen
Copy link
Contributor Author

Technically speaking, I'm not certain if this is possible at the moment. How would you decide to trigger the collapsed variation for a Toolbar? How do you choose which Toolbar to trigger first?

Let's work out the ground rules and tweak them until we find an approach we can get to work. Here's one suggestion for ground rules:

  • A segment has two states, collapsed or not collapsed.
  • Segments collapse left to right. If the sequence is [switcher] [block align] [variations] [alignments] [inline], first the block align would collapse, then variations, and so on.
  • That which would trigger a collapse would be that the width of the toolbar would be wider than the block, then it would collapse either until it fit (collapsing left to right) or until it could collapse no further

For starters, we could start with just the alignments and allowing those to collapse.

Do these ground rules inspire any technical solutions that are feasible?

@youknowriad
Copy link
Contributor

@jasmussen Actually no. The problem is:

When the toolbar detects that there's not enough space, it has to "inform" its latest segment that it needs to collapse. But it can only say, collapse everything or don't collapse everything, because the detection of the available space is done on the Toolbar level using DOM and since we're using Slots to render the "segments" the Toolbar doesn't have any access to the components controlling the UI of the segments.

@jasmussen
Copy link
Contributor Author

Thanks for the clarification. I'll think a bit about this and see what configurations we might look at.

But for now, what if we said that all segments, except inline formatting, could collapse? Would that simplify things? Yes be fine if all those collapsed at once.

@youknowriad
Copy link
Contributor

But for now, what if we said that all segments, except inline formatting, could collapse? Would that simplify things? Yes be fine if all those collapsed at once.

Yes, that's definitely possible.

Smart collapsing

Not saying I have all the answers, just that It's very hard, I have some weird ideas I'll try to experiment with but definitely too complex. Others might have some ideas on the subject.

@karmatosed
Copy link
Member

This is a great idea to increase understanding. I do wonder how discoverable without a drop down indication is, but that is something to consider as we rely more heavily on this.

@karmatosed karmatosed removed the Needs Design Feedback Needs general design feedback. label Aug 20, 2018
@jasmussen
Copy link
Contributor Author

Not saying I have all the answers, just that It's very hard, I have some weird ideas I'll try to experiment with but definitely too complex. Others might have some ideas on the subject.

I'm #teamriad. But it's always good to get a baseline and then improve from there. If there's an easy path forward that gets us most of the way, seems like a good place to start.

@ZebulanStanphill
Copy link
Member

I also agree that just having all the tool groups (or all but the inline tool groups) collapse is a good first step and an improvement over master.

@afercia
Copy link
Contributor

afercia commented Aug 21, 2018

Apart from the technical challenges mentioned above, I'm not fully sure this could work well from an accessibility perspective.

Keyboards and screen readers are used also on mobile devices. Yes, keyboards 🙂and it's a growing trend.

https://webaim.org/projects/screenreadersurvey7/#mobilekeyboard

Mobile devices are often considered to be touch-only interfaces, yet many screen reader users use a keyboard when using their mobile devices.

That said, all the drop-downs should communicate semantically they're menus, and be implemented as ARIA menus, which adds an extra layer of complexity to the implementation. Worth noting that even if implemented in a compliant way, I'm not really sure the final result would be so easy to use for keyboard and screen reader users.

I'm sorry I don't have good alternative ideas to propose at the moment, but I'd propose to explore simpler solutions.

@folletto
Copy link
Contributor

I like the collapsing approach, but given the above, it seems to have a lot of challenges.

What if we take an intermediate approach — even if less ideal than the collapsing — two ideas:

  1. The bar is scrollable horizontally, so when small it gets a fade-out to the right, but it doesn't change. Accessibility wise it will behave the same as there's no structural change, and with the fingers everything is just a scroll away.
  2. The bar instead of scrolling gets an ellipsis, that shows whatever will "fall" in the reflow.

Also to consider:

a. might be interesting to see if ••• could trigger a horizontal (potentially multi-line) bar instead of a vertical line. That would allow more scalability, and wouldn't have to change vertical/horizontal order (and preserve ease of memorization).
b. The ••• in the mock above might be too thin, smaller than the touch area of a finger on a touchscreen. Maybe not, but worth a cross-check. :D

@chrisvanpatten
Copy link
Contributor

Something like this?

untitled_5_sketch

Interesting idea but it might be awkward on desktop…

@jasmussen
Copy link
Contributor Author

Thank you Davide, your insights are always appreciated.

Horizontal scrolling is implemented on mobile, and works reasonably. We had to do some hacks in order to make dropdowns work inside the scrollable div, but I believe it should already be in place. So the challenge here is definitely desktop centric.

The idea of "popping off items" one by one into the overflow menu is definitely a solid one, this is what Google Docs does, and I tried to mock this up before what you see on this ticket. But our challenge is that we already have an ellipsis menu, which contains things that aren't really related to formatting, which is mostly the domain of the block toolbar. In practice this ended up feeling very weird and not that helpful:

screen shot 2018-08-23 at 08 38 39

I acknowledge the challenges with dropdowns, but I feel like this might be a good first step on the path. Then we can have a baseline responsive toolbar, and improve from there. What do you think?

@folletto
Copy link
Contributor

But our challenge is that we already have an ellipsis menu, which contains things that aren't really related to formatting, which is mostly the domain of the block toolbar. In practice this ended up feeling very weird and not that helpful:

I agree. Good exploration, but shows that combining isn't right.

I was more thinking of a new icon, which could not be an ellipsis but a chevron, that triggers just the overflow.

@ZebulanStanphill
Copy link
Member

@folletto You mean kind of like what Firefox has for add-on/toolbar icons? (With a horizontal layout and without the text, of course.)

image

I think that could work.

But the combined ellipsis really does not bother me, personally. Chrome/Chromium actually does something pretty similar to this, actually:

image

@folletto
Copy link
Contributor

You mean kind of like what Firefox has for add-on/toolbar icons?

I knew I saw it before, thanks I couldn't recall where :D
Yes, thanks for providing some extra background!

@karmatosed
Copy link
Member

The bar is scrollable horizontally, so when small it gets a fade-out to the right, but it doesn't change. Accessibility wise it will behave the same as there's no structural change, and with the fingers everything is just a scroll away.

This is my preference I think.

@afercia
Copy link
Contributor

afercia commented Aug 24, 2018

The bar is scrollable horizontally, so when small it gets a fade-out to the right, but it doesn't change. Accessibility wise it will behave the same as there's no structural change

Horizontal scrolling can be problematic for accessibility and ideally it should be avoided. It's not just about screen readers, there's a multitude of alternative devices to take into consideration.

Also, worth reminding on Windows there will be a visible, big, horizontal scrollbar 😞

I'd rather consider to explore what can be done with the ellipsis menu, as @folletto mentioned above.

@kevinwhoffman
Copy link
Contributor

kevinwhoffman commented Aug 29, 2018

Element queries would provide the missing information necessary to determine when there is too little space and controls need to start collapsing. Of course element queries are not a real thing yet, so a JS polyfill is necessary.

I have worked with two different solutions for element queries in the past that would be worth looking into regarding the toolbar challenges:

CSS Element Queries - This seems to be the more lightweight solution that leverages existing CSS selectors to define element queries. I was also impressed by the focus on performance as shown in the demos page.

EQCSS - This is a more powerful library that opens up a lot of possibilities regarding element queries. The downside is that it uses its own syntax and does a lot more than we need it to. But maybe there are pieces that could be leveraged.

For the purposes of detecting the width of a container and showing/hiding elements, the CSS Element Queries polyfill should do what we need.

@tomhodgins
Copy link

I like the design of the toolbars with collapsing sections, and it does seem like a perfect use-case for element queries! Since any element query solution will be powered by JavaScript (for the foreseeable future) I think you'll have to approach the design like this:

  • anywhere media queries can be used: they should be used (i.e. when the width of the toolbar has a known relationship to the width of the browser's viewport)

  • anywhere media queries cannot be used: use the smallest/narrowest design in CSS and that's the best CSS can do. Make that design work and look well, and if they happen to have JavaScript running, and if these additional "bonus styles" render, then they get an even better JS-enhanced experience

That way all of the JS-powered styles aren't replacing anything CSS can do, but only doing the things you otherwise wouldn't be able to do at all. And if the JS-powered styles fail for any reason you still have a usable, well-designed toolbar.

What it looks like this design needs to take it to the next level is a way to set responsive breakpoints based on the width of the element holding the toolbar in situations where there's no known relationship between the width of the element and the width of the browser's viewport. That's definitely something we can do!

I'm sure you're better at writing accessible HTML than I am, so rather than having me mock up HTML for a demo, is there an example of the actual markup you're working with for this menu? I've got a stripped-down element query plugin (~500 bytes of JS) that I think would work well for this toolbar, and can be controlled from (valid) CSS stylesheets, as well as from JS, and I'd love to see if I could make this design work!

@chrisvanpatten
Copy link
Contributor

@tomhodgins I think that's a fair point regarding keeping element queries to a minimum. It could easily get out of hand :)

if they happen to have JavaScript running

Gutenberg doesn't work at all if JS isn't loaded, so if they get to that point we'll have bigger fish to fry 😅 I think it's safe to assume that if they've made it into the Gutenberg UI, they have JS available to them.

@youknowriad
Copy link
Contributor

Unfortunately, CSS Element Queries or CSS can't solve the issue mentioned in this PR because the ideal behavior is not to collapse when the container reaches a certain size but the behavior is to

  • Collapse the toolbar segments successively starting from the left when the toolbar doesn't have any space available.
  • Both the segment sizes and the toolbar content and the toolbar sizes are not fixed and change from block to block, they can even change in the same block depending on the state of the block.

For me, there's no alternative other than JS computation and even with JS is not obvious how to collapse the segments one after another.

@afercia
Copy link
Contributor

afercia commented Aug 30, 2018

What it looks like this design needs to take it to the next level is ...

Accessibility 🙂Just to remind that multiple sections with multiple drop-downs would be a nightmare for accessibility (and I doubt it's even feasible). I'd totally second the proposal of one, single, additional drop-down where all the things can be moved into.

@kevinwhoffman
Copy link
Contributor

@mapk and I worked on responsive tabs for the Plugins Directory last year. He wrote some JS to collapse tabs one by one as the container shrinks. I think it could be relevant to the solution we're looking for.

Here's the CodePen with his proof of concept: https://codepen.io/mapk/full/BRWGWQ

@afercia
Copy link
Contributor

afercia commented Aug 31, 2018

responsive tabs for the Plugins Directory

I like the idea. Pretending to not see the list items are not usable with a keyboard, not semantic, and the click event is attached to the list items 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants