Closed kleinfreund closed 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).
The current solution is a best-of-two-worlds approach:
scrollLeft
of the scrolling HTML elementwheel
event if the user is holding Shift while scrolling vertically (then the default action of the event is cancelled)wheel
event with a corresponding deltaX
value.), the default action won’t be cancelled and the navigation interface won’t be used.Using scrollLeft
in the navigation interface maintains interoperability with a natively scrolling container.
TL;DR:
wheel
event to implement a shortcut for horizontal scrolling (because untrusted events don’t trigger default actions).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 setelement.scrollTop
andelement.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 thewheel
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.
wheel
event. Using trackpads and the 1-to-1 mapping of wheel turn to page movement doesn’t work well, because thewheel
event is fired a lot of times. This can maybe ignored in case touch scrolling is able to cover trackpadsFurther resources:
transform: rotate(-90deg)
)