The wheel
event in Firefox >= 17 has a deltaMode
property. With the OS/mouse I'm using, it's set to 1
(or DOM_DELTA_LINE
). This setting means that the deltaX
and deltaY
event values are measured in lines and not pixels. Sure enough, if I pretend the deltas are pixels, scroll speeds are much slower than they normally are in Firefox.
Chrome 31 by contrast uses a deltaMode
of 0
(or DOM_DELTA_PIXEL
), which allows me to simulate scrolling with normal speeds.
If I could convert the line values to pixel values, I'd be all set. But I can't find a scrap of documentation about what a "line" is. I tried changing the font-size
and line-height
in Firefox, which didn't change the scrolling behavior.
Anyone know how a "line" is defined? W3C just says, "This is the case for many form controls."
Edit: here's a fiddle to demonstrate the oddity. When Firefox is in DOM_DELTA_LINE
mode, there's no consistent ratio between pixels and lines – it's all over the place. And when I switch to using a trackpad instead of a mouse, causing Firefox to switch to DOM_DELTA_PIXEL
mode, there's also no consistent ratio. On the other hand, in Chrome 31, the ratio is almost always very close to 1:1 in DOM_DELTA_PIXEL
mode.
Chromium issue: implement DOM3 wheel event
Bugzilla bug: implement DOM3 wheel event
Update: Scrolling by single ticks of a mouse wheel in Firefox where deltaMode
is DOM_DELTA_LINE
, the pixel delta is dependent on the CSS font-size
, but not on line-height
. See this fiddle for a demonstration. This behavior only holds when ticking the wheel very slowly. With speed or momentum, the line to pixel ratio isn't predictable at any particular instance or in aggregate. As far as I can tell, there's no way to emulate Firefox's scroll behavior using the delta measurements provided in DOM_DELTA_LINE
mode.
In DOM_DELTA_PIXEL
mode, the behavior is nearly pixel-perfect. That is, the ratio between actual pixels scrolled and the reported pixel delta value is almost exactly 1, which is demonstrated in the the same fiddle.
I filed a bug with Mozilla, arguing that the behavior of the wheel
event in DOM_DELTA_LINE
mode isn't useful because it isn't predictable (i.e., it's an equation where both the unit and the magnitude are variables). The issue has been marked invalid because the expected behavior is for the wheel
event to pass through the native deltas provided by the OS, despite the fact that Firefox itself doesn't honor these deltas.
I'll leave this question open in the hope that DOM_DELTA_LINE
will be defined by a spec somewhere. As far as I know, the dependence on font-size
(and not line-height
) isn't yet described anywhere.
Best Answer
Overview:
While the scroll value resulting from
DOM_DELTA_LINE
may not be specifically defined by any specification, based on the following comment from the Chromium issue tracker and my own observations, it appears that Firefox is presently the only browser that will report wheel events with anything other thandeltaMode
asDOM_DELTA_PIXEL
(0
).Comment from Chromium issue Implement DOM3 wheel event:
According to that comment, Chromium matches IE's only-pixel deltas. Though not covered, this almost certainly extends directly to modern Opera and Safari. My own observations from testing on Window, Mac, and Linux with multiple input devices did not disprove this.
So since Firefox is the only browser that will report a
deltaMode
ofDOM_DELTA_LINE
(1
) orDOM_DELTA_PAGE
(2
), for the time being anyway, we only need to know what Firefox computes these values as. Well, that's where things get a bit tricky, but through searching through the Firefox source and some trial and error, I've determined it directly corresponds the default font and default font-size. Specifically those configured in the following preferences, ignoring any CSS on the page.That means that to correctly detect the line-height used in scrolling, you must have a completely un-styled inline element to detect the computed rendering height from. Since CSS on the page will almost certainly interfere, we must create a new and clean window in an iframe to do the detection.
Detecting the line-height used by
DOM_DELTA_LINE
triggered scroll events:For this purpose, I have created the following little function to synchronously detect the pure, unaltered line-height.
Ok, so now we know just how much a line-height delta should translate to in pixels. However, on Window, there is one other thing that you may need to take into consideration. On Windows, the default scroll speed is overridden to make it 2x faster by default, but only for the root element.
Override system of system scroll speed:
This is only applicable by default to the root of the document, scrolling elements within the document like a
textarea
are not affected (except maybe iframes?). There's also no way to get the specified value if the default 2x is reconfigured, so if you deem this value important, you will have to resort to user-agent OS sniffing, perhaps with the technically non-standard yet popularnavigator.platform
.What about
DOM_DELTA_PAGE
?:Windows also has an alternate setting for vertical scrolling where instead of scrolling by the number of lines, it scroll by an almost full page. To clarify, this is the dialog with the "One screen at a time" setting controlling this in Windows 7.
When this is activated, a single click will scroll almost a full page, here meaning the height of the scrolling panel, minus the scroll bars. I say almost, because Firefox takes some other things into consideration to reduce the amount of scrolling. Namely, reducing by some lines, a percentage, and somehow subtracting the fixed position headers and footers. See the following block of code for some of the logic.
Excerpt from
layout/generic/nsGfxScrollFrame.cpp
:I'm not 100% sure what exactly is detected as a fixed position header and footer element and what isn't, but this should give a pretty good overview of how the
DOM_DELTA_PAGE
mode also works, in addition to theDOM_DELTA_LINE
which this question asks about.