webis-de / slidehub

Generic code for slidehub pages
MIT License
2 stars 1 forks source link

Horizontal page navigation: The big scrolling issue #9

Closed kleinfreund closed 6 years ago

kleinfreund commented 7 years ago

TL;DR:


The issue

Document pages are laid out horizontally and overflow if needed. All interaction techniques need to be able to access the overflowing pages.

The default behavior is using scrollbars to a) indicate that additional content is available and b) navigate to that content. If however overflow: hidden; is set, scrolling the container is not possible with regular means. One can still set element.scrollTop and element.scrollLeft.

We do not want to show the scrollbars due to cosmetic reasons. This would also disable any scrolling capability. I managed to visually hide the scrollbars by nesting the scrolling container in another element which is set to have the exact same height as the inner element containing the actual content (Demo on codepen: Hide scrollbars without disabling scrolling).

The requirement of hiding the scrollbars all pointer-based interactions with the scrollbar itself are no longer available. Therefor, another interaction technique needs to be available. Commonly, applications use the Shift modifier while truning the mouse wheel to scroll horizontally. Unfortunately, browsers haven’t converged on this behavior yet. Firefox, Internet Explorer and Edge have no shortcut for horizontal scrolling. Instead they navigate the browser history (the turning a wheel metaphor is not correct for such an interaction).

Note that it is not possible to trigger the native scrolling action programmatically. I can’t hijack Shift+Wheel and create a synthetic wheel event that scrolls horizontally. This is explained in more detail in a question I posted on Stack Overflow: Programmatically trigger horizontal scrolling (the default action of a wheel event).

I conclude that there generally is no cross-platform interaction technique for horizontal scrolling for mouse users. This ignores dragging the scrollbars which I do not consider an easy technique; it’s rather cumbersome.

Possible solutions

Re-implement scrolling for all platforms

One solution is completely re-implementing scrolling. This is a very hard task which has been tackled by many different parties so far. Browsers widely support the wheel event, but it’s inconsistent. Especially the delta values (e.g. event.deltaY) can’t be used without normalization. Quickly trying it in Chrome and Firefox already yields different results: 53 and 3. Furthermore, some browsers fire the wheel event more often with small deltas when the user is scrolling faster. Trackpad-triggered events are also fired a lot (as in a LOT) since every tiny bit of movement is treated as one event.

This doesn’t even consider inertial scrolling on mobile devices right now. Scrolling on desktop platforms is rather straight-forward. As soon as one stops turning the scroll wheel, the scrolling action is also done. Intertial scrolling however may keep on scrolling depending on how much distance was scrolled in a certain amount of time. Scrolling a long distance in a short time leads to a relatively long overall scroll distance while slowly panning a page results in the exact same scroll distance that the page was panned.

In short, there is no easy solution to re-implementing scrolling or even normalizing the wheel event. It puzzles me that browser vendors didn’t sit down to do that, yet. Why does a turn of my mouse wheel scroll the exact same distance on Chrome and Firefox but yield different delta values?

Re-implement scrolling for Firefox/Internet Explorer/Edge

Only Firefox/Internet Explorer/Edge don’t offer a good interaction technique for native horizontal scrolling. I think it should be possible to re-implement scrolling for these browsers.

This, however, requires browser detection. Ideally I would know which browsers need the re-implementation and use browser detection to filter. Right now, I plan to maintain a blacklist of browsers that don’t have a sane horizontal scrolling shortcut. For browsers on this blacklist, a custom scrolling implementation will be used.

For browser detection, we could rely on an external library with the benefit of being better tested and the drawback of offering more functuinality than we need. Basically, we only need to detect if a browser is either Firefox, Internet Explorer or Edge.

Roadmap

Basic custom scrolling is implemented. It allows navigating document pages one page at a time. With a pointer device, this already feels good. Each turn of a scroll wheel moves the active page while staying to the grid.

The current implementation however does not work great with touch-based interaction. The reason for this is a lack of inertial behavior as it is common on mobile devices. Without it, navigating feels slow and cumbersome.


Further resources:

kleinfreund commented 6 years ago

Firefox Nightly was shipped with a new default action for Shift+Wheel, solving a 16-year-old issue (Horizontal Scrolling with Mouse wheel+ modifier key).

Starting with the release of Firefox 58, only Microsoft Internet Explorer/Edge lack a native interaction for horizontal scrolling with a regular mouse. I proposed adopting horizontal scrolling like Firefox did over on the Microsoft Edge issue tracker (Change default action for Shift+Wheel to scroll horizontally).

kleinfreund commented 6 years ago

The current solution is a best-of-two-worlds approach:

Using scrollLeft in the navigation interface maintains interoperability with a natively scrolling container.