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

[css-ui-4] pointer-events should have a filtering capability #6280

Open
astearns opened this issue May 10, 2021 · 5 comments
Open

[css-ui-4] pointer-events should have a filtering capability #6280

astearns opened this issue May 10, 2021 · 5 comments
Labels
css-ui-4 Current Work

Comments

@astearns
Copy link
Member

Once #4438 has the currently implemented version of pointer-events added to css-ui, we should take a look at the feature requests in https://wiki.mozilla.org/SVG:Pointer-events and our own issue list. One item on the Mozilla wiki is

Provide a way to filter which pointer events are intercepted by an element. For example, to specify that an element should intercept most pointer events, but not mouse wheel events. This would allow elements with fixed position to pass wheel events on to the elements below them.

There is also a request in #4499 to have a value that just stops events (instead of passing them through). I think it would be useful to combine these ideas and allow a CSS declaration that declares which events are handled, which are passed through, and which are stopped.

The particular case that led me to opening this issue is an overlay where we want it to respond to hover events, but have click events pass through to the element underneath.

@astearns astearns added the css-ui-4 Current Work label May 10, 2021
@SebastianZ
Copy link
Contributor

I believe pointer-events should rather have been introduced as some kind of JavaScript API as it defines the interaction with elements. But here we are now and the property is supported everywhere for a long time.

Therefore, it somewhat makes sense to me to extend that property to filter the events it handles. An important question is how fine-grained the control should be that authors have over events. E.g. does it make sense to allow hover events, pass through move events and stop any other events? Do people want to pass through pointer down events but stop pointer up events?
And which of those possibilities are better left to JavaScript?

Sebastian

@aeharding
Copy link

As a web developer, my use case is a simple css scroll snap carousel with left/right buttons on desktop.

(Example: https://snap.glitch.me/carousel.html)

If the user is hovering over the left/right buttons while attempting to scroll, it doesn't scroll the carousel. (This is worse if the buttons are touch friendly/bigger.) Even worse, on horizontal scroll views on a Mac, this causes horizontal scroll to be redirected to the document root which causes the browser to navigate (forward/back).

Workarounds I've tried:

  1. Use pointer-events: none; and attach to document mousemove/click events to essentially reimplement interaction with JS. Obviously, this is not great for many reasons, and is flakey due to this Chrome bug
  2. position: sticky can be (ab)used for the back/forward buttons when placed inside the scrollview. However, each click event inside a scroll view causes smooth scrolling to stop and/or stutter - badly on Firefox. (I've also not been able to override this behavior with e.preventDefault()

At this point, there's no good solution. This is made worse by there being no way to determine if the user is interacting with a touchpad or via a mouse - so I can't just remove the buttons if the user has a touchpad.

Solution

pointer-events: no-wheel; or similar.

Thank you for your consideration.

@kleinfreund
Copy link

kleinfreund commented Nov 21, 2024

This is a admittedly somewhat niche requirement I ran into quite a few times:

Keep all pointer events but disable scrollThrow away all pointer events but keep scroll. This came up in the context of cards floating on top of scroll-interactive content. I wanted the cards to "let the scroll event through" like pointer-events: none does. However, the cards need to remain interactive so they can't have pointer-events: none.

However, this also poses the immediate question of what happens when such an element itself is overflowing and should become scrollable. Then, you'd need to have a mechanism that only applies when the element doesn't even fire that event itself and that would make for an extremely confusion user experience.

In terms of API shape, a simple keyword wouldn't cut it. One would need a sort of filtering mechanism in both directions:

  • pointer-events: allow(scroll, click, ...)
  • pointer-events: deny(scroll, click, ...)

@tabatkins
Copy link
Member

@kleinfreund I think you're asking for overscroll-behavior: contain, to prevent a scroll on a card from "chaining" up to the nearest scroller (while still allowing the card itself, or its contents, to be scrollable).

@kleinfreund
Copy link

@tabatkins Apologies, I somehow managed to completely invert the requirements I had in mind while writing them down. I updated my post and also expanded the explanation somewhat.

My intention was to achieve the inverse effect: to allow a scroll on a card to "chain up" (or "through") the card and fire on the element behind it. pointer-events: none does this, but it also, of course, makes the cards non-interactive for pointer interactions (e.g. let's say for simplicity's sake the card would only have links).

Most likely this one of these cases where in isolation, such an API could make sense, but overall, it's probably too big of a UX infraction if not handled extremely carefully should the card itself need to have any scrolling content.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
css-ui-4 Current Work
Projects
None yet
Development

No branches or pull requests

5 participants