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

Vertical scroll #11

Closed
alexWhitworth opened this issue May 1, 2020 · 12 comments
Closed

Vertical scroll #11

alexWhitworth opened this issue May 1, 2020 · 12 comments

Comments

@alexWhitworth
Copy link

Computer mouses and web browsers are built for vertical, not horizontal, scroll. This repo would be far better if it was designed for the user to scroll vertically vs horizontally.

@kunalsinghal
Copy link

But it's just amazing on phones!

@MKorostoff
Copy link
Owner

Yeah, this is something we talked about a little in another thread. Copying my comments there:

Yeah, I've thought a lot about this. I think ultimately horizontal scrolling was a bad choice to begin with, and I wish I'd made it vertical scrolling. I actually took a run at converting the whole thing to vertical scroll at one point, but it was just too much work, and now that there's like 10,000 people tweeting "check out this amazing SIDE SCROLLER, remember to SCROLL RIGHT" I feel like I'm stuck with it.

I've tried to think of a simple small fix that would solve the problem without necessitating a massive re-write, and I haven't really come up with anything. One person suggested that I listen for the mousewheel event, and convert vertical scrolls to horizontal scrolls—I guess in principle that could work, but it results in some pretty heinous scrolljacking. This is the approach they took on 1 pixel moon (which, sidenote, was my direct inspiration) but it feels super unnatural to me and I hate it.

Another thing I've considered is trying to add some sort of message to the user explaining that they can hold shift while using the mousewheel to produce a horizontal scroll, or that their mouse likely has a physical horizontal scroll built in, or that they can use middle click for omnidirectional scroll. The trouble there is that it's confusing for people on trackpads (i.e. pretty much all laptops) who instinctively scroll left and right with finger gestures all the time. If I show some message like "hold shift to scroll" I guarantee some portion of track pad users will think it applies to them.

To be honest, I don't really know the solution, but I'm open to suggestions. Maybe I could try to detect the device based on user agent and only show the message to a subset of users, but that has some downsides too.

That all said, it's worth noting that folks without horizontal scroll are a tiny minority of my traffic. Around 75% of my traffic is from mobile devices. Around 10% is mac desktops (which all have horizontally scrolling mice/trackpads) and around 10% comes from windows desktops (almost all of which have horizontal scroll, though probably not many people know how to use it). I would guess somewhere between 1% and 6% of my traffic comes from people who either physically can't horizontally scroll or don't know how. I want to support this use case, but the solution shouldn't diminish the experience for the majority of users. I'm open to suggestions how that can be done.

@alexWhitworth
Copy link
Author

Thanks for the very thoughtful, and data driven, response

@MKorostoff
Copy link
Owner

Thinking about this a bit more, I think I like the solution in which we show a subset of users the "hold shift to scroll" message. It avoids scrolljacking, maximizes performance, and actually gives the user a little skill they didn't have before coming to the site. For users on touch devices or trackpads, nothing would change.

The key question is: how do we appropriately target just the mousewheel people, without showing an irrelevant, confusing message to non-mousewheel people. The solution should exclude all mobile/touch devices (easy) exclude all macs (easy) and include Windows/Linux devices unless the user is using a track pad (mega-hard, bordering on impossible). There's no way we could perfectly segment the two groups, but could we get close enough?

A couple of ideas:

  • Show the message if 1) window.navigator.platform contains "Win" or "Linux" 2) css device width is greater than, say, 1200px. This would include a lot of track pad devices, but maybe it helps more people than it hurts? Not sure.
  • Use a more advanced JS hardware API to infer the likely existence of a non-trackpad mousewheel. For instance, what if we used navigator.keyboard to check for the existence of a number pad. I think we can mostly assume that a device with a number pad is a desktop with an attached mouse and mousewheel, even if this does include a few trackpad devices. Main problem here is that browser support is very bad, pretty much Chrome only.
  • Differentiate between laptops (assumed to be trackpad) and desktops (assumed to be mousewheel) through the battery api. Again, main problem here is browser support. Also, a plugged-in fully charged laptop would detect as desktop.
  • Detect touchpad vs. mousewheel by analyzing the cadence of the wheel event. This is the most accurate solution, I think, and almost perfectly segments the two groups. The major (insurmountable?) downside is that this only works once the user interacts with the wheel/trackpad. So we'd only know they're a mousewheel user if they attempted to unsuccessfully scroll down. I can't imagine too many users are going to interact with the vertical mousewheel when there's already a message right there on screen telling them to scroll right.

Now, having written all that out, I'm not sure if any of those methods would be reliable enough to be worth implementing. Maybe I should take another look at the approach where we translate vertical scroll events to horizontal scroll—I just feel that's gonna break on some devices, and it will be really hard to test cross-platform. Ack, maybe there's no solution after all.

@MKorostoff
Copy link
Owner

Ok, tried my hand at fixing the problems noted in #11, on the branch feature/horizontal-scroll. The general idea is to 1) listen for the mousewheel/DOMMouseScroll event 2) convert vertical scrolls to horizontal scrolls unless 3) the event.target has the attribute data-vertical-scroll="true" and finally 4) attach the data-vertical-scroll attribute to all the vertically scrollable elements. This solves the problems noted in that pull request, namely you are now able to vertically scroll the 60% counter and malaria babies, and there's no more console errors. Unfortunately, this creates a new problem, which is that, once you enter a vertical scrolling element, you're mouse is trapped:

scroll

It is possible to break out of the trapped mouse situation by A) moving the mouse outside the vertically scrollable element or B) using native browser horizontal scroll (keyboard arrows or trackpad swipe right). But I feel like that's a way more surprising, unintuitive experience that just demanding that the user horizontally scroll in the first place. Also, if you move your mouse to the left of the scrollable element, you'll just get trapped again. If a use didn't know about omnidirectional scroll I think there's a slim chance they'll be able to figure out how to escape the mouse trap.

So, yeah, I think the idea of using vertical scroll wheel to produce horizontal scroll with JS is pretty much dead. We can maybe still find a solution that gives the user better instructions though.

@ChildishGiant
Copy link

I started working on a vertical version by abusing css transforms but gave up. If anyone wants to pick it up it's here https://github.com/ChildishGiant/1-pixel-wealth/tree/vertical

@BryceBeagle
Copy link

The key question is: how do we appropriately target just the mousewheel people, without showing an irrelevant, confusing message to non-mousewheel people.

Why not just have the message appear whenever a user attempts to scroll vertically? It can then disappear again when the user starts scrolling horizontally.

@clugg
Copy link

clugg commented Jun 16, 2020

Unfortunately, this creates a new problem, which is that, once you enter a vertical scrolling element, you're mouse is trapped

You could modify your convert_vertical_to_horizontal scrolljacker to also consider the target's current scrollbar position.

If e.target.scrollTop === 0 and the user is scrolling up, let the scrolljacker take over (so when a user scrolls up at the top of a vertical scrolling box, the scrolljacker does its thing and starts scrolling left).

If e.target.scrollTop === e.target.scrollTopMax and the user is scrolling down, let the scrolljacker take over (so when a user scrolls down at the bottom of a vertical scrolling box, the scrolljacker does its thing and starts scrolling right).

I think this is fairly intuitive.

@rupertjeff
Copy link

The solution should exclude all mobile/touch devices (easy) exclude all macs (easy) and include Windows/Linux devices unless the user is using a track pad (mega-hard, bordering on impossible).

Anecdotally, I use a Mac and an external (not Magic) mouse, so I would fall into the camp of "Mac but not Trackpad". Definitely understand this is a small use-case for this site. Either way "exclude all macs" might not be the ideal solution, if avoidable.

@MKorostoff
Copy link
Owner

FIxed in d979df2. The solution I went with is (on desktop devices only) if the user attempts to scroll down or moves their mouse, I start a timer. If the user still hasn't figured out how to scroll right once the timer elapses, I display the text "To scroll right, use shift + mousewheel. If you have a touchpad, swipe sideways." The timer is 2 seconds for a downward scroll and 4.5 seconds for a mousemove.

This is pretty similar to the approach suggested by @BryceBeagle, which I'd previously ruled out because I felt it wasn't inclusive enough. I worried that not enough people would even attempt to scroll, but instead just sit there baffled. I think this is addressed by listening for mousemove events as well mousewheel events. This also addresses the concern raised by @EatTheRichTextFormat that some users may think the scroll indicator is actually a clickable button, rather than just an instruction.

I abandoned the idea of trying to differentiate touchpad users from mousewheel users after extensive testing showed the cadence detection strategy to be too unreliable. Given that we can't stop people with touchpads from seeing this message sometimes, I decided to add language that includes them—without this, I'll certainly get people trying to hold shift and touchpad-swipe up/down, which does not work. I decided to include Macs based on the comment from @rupertjeff, who correctly points out that some Macs have a non-magic mouse plugged in.

I looked into the suggestion by @clugg, but determined it's not workable because users would need to scroll all the way to the very bottom of each vertically scrollable elements in order to un-trap their mouse, which no one will ever do. One of these elements is 200 million pixels tall! I've never even scrolled it to the end.

Additionally, I updated the initial on-screen instructions to read "Scroll right" instead of just "Scroll" so hopefully more people get it right off the bat without needing the additional instructions.

I'm sure there will be some cohort of users who find the new messaging even more confusing, or have some special hardware setup my messaging doesn't anticipate. I'm also sure some people will view this message as an invitation to criticize the UX ("If you know it's confusing, why not fix it?" Answer: because it's too much work). And while it would be nice to have perfect instructions for every single user in every single hardware configuration, I have to balance that with the need to provide a simple, decluttered experience for everyone else who already knows how to scroll.

@BryceBeagle
Copy link

Just a thought: With how much scrolling this page requires, I think it would be better to recommend using the arrow keys to scroll instead of the mouse wheel. It also has the added benefit of providing a linear scroll rate.

@MKorostoff
Copy link
Owner

@BryceBeagle thank you for the suggestion, but I do not agree

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants