Open masayuki-nakano opened 6 years ago
Bug of Firefox is here: https://bugzilla.mozilla.org/show_bug.cgi?id=1392460
If it'd be possible, there should've been:
@garykac Could you take a look? This is really annoying Spec issue. (Perhaps, some Chrome for Windows users have same issue as users of Firefox for Windows or Linux users since Chrome uses DOM_DELTA_PAGE if user sets per-page-scroll in the system settings.)
To summarize the proposal:
Because many web developers don't respect the deltaMode
setting and simply assume that delta*
always returns pixel values, we're proposing changing delta*
to always return pixel values.
deltaMode
to always return DOM_DELTA_PIXELdelta(X|Y|Z)
to always return pixels values
rawDelta(X|Y|Z)
and rawDeltaMode
so that sites that want the non-pixel deltas, can explicitly request it.
deltaX
and deltaMode
. Although browsers may choose to return LINE or PAGE since PIXEL is already covered.This change won't affect sites that properly check the deltaMode
attribute, but it would break any site that assumes Firefox == DOM_PIXEL_LINE without actually checking deltaMode
.
Sites that currently take advantage of Firefox's non-pixel deltas will no longer do so until they switch to use the new attributes on the event.
FYI: As far as I've tested, deltaMode value of each browser:
DOM_DELTA_PIXEL
DOM_DELTA_PIXEL
DOM_DELTA_LINE
DOM_DELTA_PIXEL
DOM_DELTA_PAGE
DOM_DELTA_PAGE
DOM_DELTA_PIXEL
DOM_DELTA_PIXEL
DOM_DELTA_PIXEL
DOM_DELTA_PIXEL
DOM_DELTA_PIXEL
DOM_DELTA_LINE
DOM_DELTA_LINE
DOM_DELTA_PIXEL
@rbyers @travisleithead Any thoughts on this proposal?
I've seen this difference between Chrome and Firefox cause real compat problems on real sites, so I support trying to fix it. I agree that delta is so often pixel that it's safer to require that it ALWAYS be pixel.
So the proposal seems reasonable to me, though I worry we might just have the same problem with rawDeltaMode
. It seems to me having any property whose units vary based on another property is potentially problematic. Why not have linesDeltaX/Y
and pageDeltaX/Y
values (which could be undefined
)? The Z
axis almost certainly doesn't make sense for lines/pages, right? Does the X
axis have a sensible and useful definition for lines
?
Anyway @NavidZ is the Chrome expert here, so this is just my $0.02 - I don't have objections either way.
Let's try to get some momentum going on this one again :)
@NavidZ, mind chiming in with your thoughts?
@masayuki-nakano, what do you think about the concern @RByers raised?
For what it's worth, I feel Rick has a good point and suggestion here. I feel that the default behavior should be consistent, as in my experience working on webcompat, web pages almost always presume pixel values and aren't even aware that there are other potential units. I feel that making the existing property a legacy (and pixel-only) value would be best, along with new properties that are specific to the units.
In fact I wonder if there is even a need to have "pages" and "lines" values at all (as well as a variable default unit)? I also wonder if they aren't a potential fingerprinting vector in some way?
(Sorry, I didn't realize the mention here.)
Yes, sounds like that's great idea. I agree with it.
However, I have a concern about implementing it. For making it, each implementation should have computed value of lineDeltaX/Y
and pageDeltaX/Y
or line height or page height/width for computing them later since events may be stored with variables and may be referred later (i.e., after ending the propagation).
I don't mind the cost as a developer of Mozilla DOM Events, but I'm not sure how other browser developers.
And in my understanding, the line height, page width and page height values are used the value at dispatching wheel
event rather than the attributes are accessed. So, I hope that UI Events should define:
@masayuki-nakano could you add the unit in which the values(deltaX/Y/Z) are actually returned to your list above? I found that, on Windows, when set to multiple line scroll, the actual unit is always lines, and when set to pages it is always pages. Though I have neither a macOS nor a Linux device. Are they always returned in lines? I am especially wondering about macOS with trackpad, since firefox also uses pixels there.
@CWies Isn't you asking about what I commented in https://github.com/w3c/uievents/issues/181#issuecomment-392648065 ?
@masayuki-nakano As I understand, thats what deltaMode returns in each browser. Though I need to know in which unit deltaX/Y/Z are actually returned, because in my testing, both edge and chrome, while returning DOM_DELTA_PIXEL
for deltaMode, only give values of 1 for deltaX/Y/Z every time i turn the scrollwheel to the next step, which is actually 1 Line and not 1 Pixel(as far as i understand)
I need to know in which unit deltaX/Y/Z are actually returned
The value can be checked with deletaMode
as you know.
because in my testing, both edge and chrome, while returning
DOM_DELTA_PIXEL
for deltaMode, only give values of 1 for deltaX/Y/Z every time i turn the scrollwheel to the next step, which is actually 1 Line and not 1 Pixel
Don't you see a lot of wheel
events in such case? If so, the device tries to scroll smoothly with splitting one action to multiple wheel events.
Don't you see a lot of wheel events in such case?
No... both on edge and chrome not
The value can be checked with deletaMode as you know.
Why the whole discussion then? Shouldnt something like
if (mode == 0) multiplier = 1; else if (mode == 1) multiplier = Number( window .getComputedStyle(document.body) .getPropertyValue("font-size") .match(/\d+/)[0] ); else if (mode == 2) multiplier = window.innerHeight; else multiplier = 0;
solve any problems? I mean it shouldnt matter in what unit they are returned, as long as you know the unit...
@CWies because we got some web-compat issues which some web apps don't check deltaMode
even though they refer delta(X|Y)
.
Well but that should be their issue, right?
@CWies Right, but such web developers check only on Chrome typically (meaning which has most market share). Therefore, other browsers may need to use same behavior (i.e., using DELTA_MODE_PIXEL
) for their users. However, if all browsers just do so, web developers who want raw delta value of native events cannot treat them anymore. Therefore, before switching Firefox's behavior, I suggest new API to retrieve raw delta value.
See also Intent to ship: Return pixel deltas in wheel event if deltaMode is not checked by authors
( s/WheelEvent.delat/WheelEvent.delta/ in the title )
A bit of status here.
Note that this debate was referenced in https://github.com/svgdotjs/svg.panzoom.js/issues/67 And this is the way they fixed it https://github.com/svgdotjs/svg.panzoom.js/pull/68/files
We are also having yet another discussion on zoomPan function for openstreetmap related to the same topics. https://github.com/webcompat/web-bugs/issues/73148
In Mozilla bug, deltaMode default should be DOM_DELTA_PIXEL, @emilio exposed DOM_DELTA_PIXEL rather than DOM_DELTA_LINES to the web
Important: https://bugzilla.mozilla.org/show_bug.cgi?id=1392460#c34
It returns pixels unless deltaMode is checked before getting the delta. If you prefer pixels, you can get the delta before checking deltaMode (and deltaMode would return pixels with the fix for this bug).
This is available only on Nightly so far.
Important: https://bugzilla.mozilla.org/show_bug.cgi?id=1392460#c34
It returns pixels unless deltaMode is checked before getting the delta. If you prefer pixels, you can get the delta before checking deltaMode (and deltaMode would return pixels with the fix for this bug).
This behavior is now shipping in Firefox but is causing confusion for web developers, see https://github.com/pixijs/pixijs/issues/8970
I think we should instead do what @RByers suggested in https://github.com/w3c/uievents/issues/181#issuecomment-394918199
@NavidZ and @smfr do you have thoughts about @masayuki-nakano computation cost concern in https://github.com/w3c/uievents/issues/181#issuecomment-537811017 ?
This behavior is now shipping in Firefox but is causing confusion for web developers, see https://github.com/pixijs/pixijs/issues/8970
Wow, that oddity tripped me up bad.
I'd like to propose that UI Events should declare that WheelEvent.delatMode always return WheelEvent.DOM_DELTA_PIXEL and WheelEvent.delta(X|Y|Z) are delta values in pixels
Even in cases when this is already true across browsers, deltaX/Y/Z vary wildly not only across browsers, but across operating systems, and maybe even across hardware.
Is there something we can add to specs to fix this so that we can get a value that is consistent across all browser and OS combinations?
Uses cases where this it is problematic is when building custom interaction using mouse and touchpad scroll, for example zoom controls for a 3D scene using canvas (webgl/webgpu) for custom rendering. It is nearly impossible to make the behavior of a custom interaction behave the same in all browser/OS combos, so much so that most people just pick a sensitivity value that is good enough across all browsers (a little slow in some, a little fast in some, but overall acceptable across all).
And even today after the Firefox bug with is already fixed, the deltaMode
behavior still varies across browsers.
Examples of inconsistencies in the wild:
I would like to also add that on macOS the scroll direction can be flipped (natural vs normal) which renders scroll-based interactions that don't scroll content (as @trusktr mentioned) inconsistent unless the scroll event includes this information (if the direction is flipped). Not to mention macOS's inertial scrolling.
For context, I'm a developer of an online data visualizer for exploring satellite data on a map (the Ocean Virtual Lab is an example). The scroll interaction is used in multiple components:
<input type=range>
-like inputs (changes in steps, or continuously)And I have yet to find a way to iron-out the inconsistencies in scroll events between different browser and platforms 😔
PS: I apologize if these problems are out-of-scope for this issue, I just don't know where else to go
After conducting a survey on wheel deltas, I found the deprecated wheelDelta*
properties are generally more consistent across platforms and browsers.
Motivated by these findings we updated the web app mentioned above to use wheelDelta*
properties, except on Apple systems (macOS, iOS, iPadOS, ...) for which we still use delta*
properties.
Example:
function getWheelDelta(event) {
if (isApple) {
// Note that deltaMode MUST be accessed BEFORE delta* in order to get
// non-pixel values in Firefox.
// See https://github.com/w3c/uievents/issues/181
switch (event.deltaMode) {
default:
case event.DOM_DELTA_PIXEL:
return [event.deltaX / 120, -event.deltaY / 120];
case event.DOM_DELTA_LINE:
case event.DOM_DELTA_PAGE:
// Discard the delta value, just take the sign
return [Math.sign(event.deltaX), Math.sign(-event.deltaY)];
}
} else {
return [-event.wheelDeltaX / 120, event.wheelDeltaY / 120];
}
}
@zaygraveyard what do you use for isApple
?
@karlcow The detection is based on navigator.platform
and is very basic, but works well enough:
const isApple = /^Mac|iPhone|iPod|iPad/i.test(navigator.platform);
Currently, unit of WheelEvent.delta(X|Y|Z) value is defined by WheelEvent.deltaMode in UI Events. However, Chrome and Edge almost always fire wheel events with WheelEvent.DOM_DELTA_PIXEL. Therefore, a lot of web sites are broken on Gecko which is the only browser firing wheel events with native event's units.
So, for backward compatibility, WheelEvent.deltaMode should return always WheelEvent.DOM_DELTA_PIXEL, unfortunately. However, some better web application developers may want raw delta(X|Y|Z) values as far as possible.
Therefore, I'd like to propose that UI Events should declare that WheelEvent.delatMode always return WheelEvent.DOM_DELTA_PIXEL and WheelEvent.delta(X|Y|Z) are delta values in pixels. Additionally, there should be alternative attributes which are set raw event information. E.g., WheelEvent.rawDelta(Mode|X|Y|Z).