Intent to Implement: Percent-based scrolling

941 views
Skip to first unread message

Matt Amert

unread,
Sep 26, 2019, 7:33:06 PM9/26/19
to blink-dev
Contact emails

Design doc

Summary
Percent-based scrolling is a feature which changes mousewheel and keyboard-initiated scrolls to be interpreted as a percentage of the size of the intended scroller, instead of being translated directly into pixels as they are in Chromium today.

Motivation
In Chromium, one "tick" of the scroll wheel or arrow key press will translate to a fixed value in logical pixels. For a mouse wheel tick on Windows with default settings, this translates to be 100 logical pixels.

Although this works well for most cases, it causes problems on smaller scrollers. When the scroller viewport is only a few hundred pixels tall, each scroll tick will scroll the viewport by a large fraction of the visible content. This is often annoying, as it is more difficult to read or keep track of the material being scrolled.

By instead translating each tick into a percentage of the visible bounds, the scroll distance for each tick is appropriate regardless of the size of the scroller.

Risks
Interoperability and Compatibility
As this is a modification of an existing feature which exists in all browsers, and the proposed change is still compliant to the spec, the interoperability risk is minimal. That being said, we discuss in the design document whether the spec should be changed based on some issues we’ve run into. If we decide to go that route, we will have to revisit the interoperability risks.

For compatibility, this feature will change the value that Chromium surfaces to the event handlers for the mouse wheel event. Assuming we resolve the percentage to DOM_DELTA_PIXELS as they are currently surfaced today, we are presented with two problems:
1. The first is that the wheel event will bubble up to all elements that have an event listener for it. These elements will not know which scroller the delta will be applied to, and so the delta largely becomes meaningless.
2. Additionally, for websites that implement some custom UI which takes advantage of the wheel event but does not relate to scrolling at all (e.g. zooming on a map), a varying delta value would likely cause issues. The delta values it would receive would depend on whatever surrounding scrollers exist; and, if there are no surrounding scrollers, the delta will be based off of the window size which is likely something that is not desired.

Anecdotally, EdgeHTML implemented this feature in a similar fashion, except the percentage for the wheel event (but not the scroll) was always resolved against the window size. Even though this technically did not adhere to the spec and was inaccurate, we did not see any compatibility bugs due to this.

Additionally, the delta that Chromium already surfaces already is not fully accurate on high DPI monitors: https://crbug.com/1001735

With these two considerations, it's likely that compatibility risk is low. That being said, we fully explore the possibilities in the section "Issues with the wheel event delta" section in the design document.

We would love to get comments and opinions regarding this.
 
Will this feature be supported on all six Blink platforms (Windows, Mac, Linux, Chrome OS, Android, and Android WebView)?
Likely no. This change is not exactly a good fit for Mac because the OS factors in acceleration for the wheel events, and percent-based scrolling would not match the look and feel of this.
However, there should be no issues supporting the other platforms.

Requesting approval to ship?
No.

Tab Atkins Jr.

unread,
Sep 27, 2019, 1:09:52 AM9/27/19
to Matt Amert, blink-dev
I'm somewhat confused. At the beginning, you say that a scroll tick on
Windows is 100 logical pixels. But later you say that the default
Windows behavior is to scroll by three lines. The latter matches my
expectation of the behavior, and isn't consistent with the former; at
default font sizes, 100px is 5-6 lines of text.

This also seems to have two unfortunate implications:

1. Scrollers full of text will no longer scroll by a predictable
number of lines (approximately, at least) - if the scroller is short,
it'll scroll by a smaller amount, possibly even a fraction of a line
per tick, but if it's long it might scroll by much more.
2. This seems to imply that very short scrollers will only scroll a
few pixels per tick, requiring a significant spin of the mouse wheel
to reveal the bottom of the scrollable area.
3. And similarly, for very tall scrollers, like large images, a single
tick might move the image a significant distance. Is there a limit on
this? Can it scroll by more than a screenful if the scroller is large
enough?

~TJ

Steve Kobes

unread,
Sep 27, 2019, 11:14:50 AM9/27/19
to Tab Atkins Jr., Matt Amert, blink-dev
On Fri, 27 Sep 2019 at 01:09, Tab Atkins Jr. <jacka...@gmail.com> wrote:
I'm somewhat confused. At the beginning, you say that a scroll tick on
Windows is 100 logical pixels. But later you say that the default
Windows behavior is to scroll by three lines. The latter matches my
expectation of the behavior, and isn't consistent with the former; at
default font sizes, 100px is 5-6 lines of text.

Chrome hardcodes a "line" to be 33.3px for the purpose of scroll delta calculation.

Matt Amert

unread,
Sep 27, 2019, 2:13:17 PM9/27/19
to blink-dev, jacka...@gmail.com, Matthe...@microsoft.com
Steve is correct, and I apologize for any confusion. The hardcode is per OS-provided line.

1. Scrollers full of text will no longer scroll by a predictable
number of lines (approximately, at least) - if the scroller is short,
it'll scroll by a smaller amount, possibly even a fraction of a line
per tick, but if it's long it might scroll by much more.
Although the exact amount of pixels scrolled will not be as predictable, the relative amount scrolled will be. It will take the same amount of scroll ticks to scroll one page regardless of the size of the scroller. Anecdotally, this feels more consistent.

2. This seems to imply that very short scrollers will only scroll a
few pixels per tick, requiring a significant spin of the mouse wheel
to reveal the bottom of the scrollable area.
On extremely small scrollers (<100 logical pixels), yes it will only scroll a few pixels. However, the current implementation in Chromium has the exact opposite problem; on scrollers too small it will scroll by more than one page, skipping content. Erring on the side of caution and scrolling less so that no content is skipped will likely provide a better user experience.

3. And similarly, for very tall scrollers, like large images, a single
tick might move the image a significant distance. Is there a limit on
this? Can it scroll by more than a screenful if the scroller is large
enough?
This is a good point. In the current implementation, there is no limit. If there happens to be a scroller on the page that is much larger than the size of the root scroller (more than ~6x in the current implementation), then yes it might happen that more than one screenful of that subscroller is scrolled. If this is an issue, it shouldn't be a problem to cap the basis for the percentage on the size of the viewport, so that no scroll can have too large of a distance.

If you'd like to try this feature out for yourself, it is already implemented (and enabled for the majority of users) on the Windows version of the Chromium-based Edge browser! Just make sure that the flag "Enable Experimental Scrolling" is turned on. In that implementation, we translate one OS-provided line into 5% of the intended scroller size, so by default it will scroll 15% of the size of the intended scroller.

Thanks!
-Matt Amert

Joe Medley

unread,
Sep 30, 2019, 2:55:46 AM9/30/19
to Matt Amert, blink-dev, jacka...@gmail.com
It seems like developers need to know this. Can someone create a Status entry?
Joe Medley | Technical Writer, Chrome DevRel | jme...@google.com | 816-678-7195
If an API's not documented it doesn't exist.


--
You received this message because you are subscribed to the Google Groups "blink-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/blink-dev/317643e1-ac21-4a4d-b757-15921bb28fa8%40chromium.org.

Alex Russell

unread,
Sep 30, 2019, 10:27:19 AM9/30/19
to blink-dev, Matthe...@microsoft.com, jacka...@gmail.com
Can one of the folks proposing the change crisply enumerate the behavior of other browsers? I see the EdgeHTML status noted, but how does this work today on Gecko, WebKit, etc?

Regards
To unsubscribe from this group and stop receiving emails from it, send an email to blin...@chromium.org.

Tab Atkins Jr.

unread,
Sep 30, 2019, 4:39:55 PM9/30/19
to Matt Amert, blink-dev
On Fri, Sep 27, 2019 at 11:13 AM 'Matt Amert' via blink-dev
<blin...@chromium.org> wrote:
> Steve is correct, and I apologize for any confusion. The hardcode is per OS-provided line.

Ah, the "we fake the line size" is the part I was missing. Thanks.

>> 1. Scrollers full of text will no longer scroll by a predictable
>> number of lines (approximately, at least) - if the scroller is short,
>> it'll scroll by a smaller amount, possibly even a fraction of a line
>> per tick, but if it's long it might scroll by much more.
>
> Although the exact amount of pixels scrolled will not be as predictable, the relative amount scrolled will be. It will take the same amount of scroll ticks to scroll one page regardless of the size of the scroller. Anecdotally, this feels more consistent.

That's why I mentioned "full of text". In my own experience, at least,
when I'm reading a long section of text, I scroll knowing that each
tick will advance a handful of lines; the exact number depends on font
size and line spacing, but it's usually 4-5 (which matches up with
what you're saying about it scrolling by 100px). If this changes so
that a scroller taller than ~700px scrolls more, possibly
significantly so, I suspect this will feel disorienting.

>> 2. This seems to imply that very short scrollers will only scroll a
>> few pixels per tick, requiring a significant spin of the mouse wheel
>> to reveal the bottom of the scrollable area.
>
> On extremely small scrollers (<100 logical pixels), yes it will only scroll a few pixels. However, the current implementation in Chromium has the exact opposite problem; on scrollers too small it will scroll by more than one page, skipping content. Erring on the side of caution and scrolling less so that no content is skipped will likely provide a better user experience.

You're right that small scrollers are currently hard to use with wheel
scrolls. I've noticed that as well and had to resort to clicking on
the scroll buttons before; it's definitely a bit annoying.

I just suspect that flicking your scroll wheel and seeing the content
advance at a snail's pace will be frustrating as well. Maybe it's
okay, since it's only 7 wheel-ticks from top to bottom; I'm not a UX
expert and have done no research.

(There might be a compromise there where the line size doesn't
decrease linearly as you get small? Still capping out at no more than
one screen-worth per tick, of course.)

>> 3. And similarly, for very tall scrollers, like large images, a single
>> tick might move the image a significant distance. Is there a limit on
>> this? Can it scroll by more than a screenful if the scroller is large
>> enough?
>
> This is a good point. In the current implementation, there is no limit. If there happens to be a scroller on the page that is much larger than the size of the root scroller (more than ~6x in the current implementation), then yes it might happen that more than one screenful of that subscroller is scrolled. If this is an issue, it shouldn't be a problem to cap the basis for the percentage on the size of the viewport, so that no scroll can have too large of a distance.

Ahhh, I see that I was misreading; it's 15% of the scroll viewport's
size, not the scrollable *content's* height like I was thinking. That
makes a lot more sense.

(But yes, capping it so that you can never scroll by more than a
screenful of content, even on very tall scroll viewports, would be
nice. No sense making short scrollers work better and tall scrollers
work worse. ^_^)

Okay, so assuming this is applied to the root scroller too, it means
that on screens ~700px tall the scroll amount won't change, but if
your screen is taller or shorter each wheel tick will be larger or
smaller than it is today?

> If you'd like to try this feature out for yourself, it is already implemented (and enabled for the majority of users) on the Windows version of the Chromium-based Edge browser! Just make sure that the flag "Enable Experimental Scrolling" is turned on. In that implementation, we translate one OS-provided line into 5% of the intended scroller size, so by default it will scroll 15% of the size of the intended scroller.

Hard for me to test on Windows, but I'll see if I can try it out at
home, thanks!

~TJ

Matt Amert

unread,
Oct 1, 2019, 6:03:35 PM10/1/19
to blink-dev, Matthe...@microsoft.com, jacka...@gmail.com
Can one of the folks proposing the change crisply enumerate the behavior of other browsers? I see the EdgeHTML status noted, but how does this work today on Gecko, WebKit, etc?

This is the behavior of other browsers today, to the best of my knowledge:

Firefox: For the mouse wheel, Firefox scrolls relative to the font size of the intended scroller and surfaces the mouse wheel event in terms of DOM_DELTA_LINE. There are two exceptions to this, however:
1. When a Windows user sets the OS setting to scroll by page, Firefox scrolls by approximately one page of the intended scroller and surfaces the event in terms of DOM_DELTA_PAGE.
2. On Macs, touchpad scrolls are based on the accelerated scroll amount sent by the OS, and surfaces the event in terms of DOM_DELTA_PIXEL.
Safari: Scrolls by the accelerated scroll amount sent by the OS for both touchpad and mouse wheel, and surfaces the event in terms of DOM_DELTA_PIXEL.
Chrome (today):
Windows – mouse wheel & non precision touch pad: When the OS setting is to scroll by lines, hardcodes a line -> pixel conversion, and surfaces the event in terms of DOM_DELTA_PIXEL. When the OS setting is to scroll by page, scrolls by approximately one page of the intended scroller and surfaces the event in terms of DOM_DELTA_PAGE.
Windows – precision touch pad: Scrolls by the pixel amount given by DManip, surfaces the event in terms of DOM_DELTA_PIXEL.
Mac - scrolls by the accelerated scroll amount sent by the OS for both touchpad and mouse wheel and surfaces the event in terms of DOM_DELTA_PIXEL.
Linux - converts the OS event into pixels and surfaces the event in terms of DOM_DELTA_PIXEL.
EdgeHTML:
Windows - mouse wheel & non-precision touchpad: Converts the OS wheel event to a percentage and resolves it against the bounds of the intended scroller. It surfaces the mouse wheel event in terms of DOM_DELTA_PIXEL. However, it resolves the percentage for the event differently than for actually scrolling; it will always resolve it against the root scroller. The delta value surfaced to javascript will therefore not be accurate for subscrollers.
Windows - precision touch pad: Scrolls by the pixel amount given by DManip, does not surface the mouse wheel event.

Matt Amert

unread,
Oct 1, 2019, 6:14:10 PM10/1/19
to blink-dev, Matthe...@microsoft.com
There might be a compromise there where the line size doesn't
decrease linearly as you get small?

We've been considering adding a minimum scroll amount so that this scenario doesn't happen, but we have yet to receive any complaints. We'll be monitoring this feature on Edge as it continues to get rolled out to get user feedback.

Okay, so assuming this is applied to the root scroller too, it means
that on screens ~700px tall the scroll amount won't change, but if
your screen is taller or shorter each wheel tick will be larger or
smaller than it is today?

Yes, for 96-DPI screens, this is correct.

Thanks!
-Matt Amert

Matt Amert

unread,
Oct 2, 2019, 5:46:08 PM10/2/19
to blink-dev, Matthe...@microsoft.com, jacka...@gmail.com
It seems like developers need to know this. Can someone create a Status entry?

We've created a status entry for this feature; you can find it here: https://www.chromestatus.com/feature/5177131258609664

Thanks!
-Matt Amert
To unsubscribe from this group and stop receiving emails from it, send an email to blin...@chromium.org.

Nico Weber

unread,
Oct 2, 2019, 8:12:27 PM10/2/19
to Matt Amert, blink-dev
This sounds more like a UI change than a web platform change. I'm not sure the blink-dev process applies for this?

(I'm pretty sure Chrome's UI here is the way it is intentionally.)

--
You received this message because you are subscribed to the Google Groups "blink-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/blink-dev/9040b54b-2eb3-4981-9f17-97fba3c2d3d0%40chromium.org.

Matt Amert

unread,
Oct 3, 2019, 8:08:04 PM10/3/19
to blink-dev, Matthe...@microsoft.com
This sounds more like a UI change than a web platform change. I'm not sure the blink-dev process applies for this?
 
(I'm pretty sure Chrome's UI here is the way it is intentionally.)

An Intent-to-Implement for blink-dev was specifically recommended as a result of this CL: https://chromium-review.googlesource.com/c/chromium/src/+/1776898

This is a change that could affect the mouse wheel event that is exposed to web pages and could also potentially have implications for the spec, so we would like to get feedback surrounding that. We specifically mention several different options in the design doc.

Thanks,
-Matt Amert
To unsubscribe from this group and stop receiving emails from it, send an email to blin...@chromium.org.

Daniel Bratell

unread,
Oct 7, 2019, 4:54:16 PM10/7/19
to Matt Amert, blink-dev

It is also ok to send out "intent to implement" just to get feedback/pushback/cheers early on. Maybe the change in the end won't need a shipping decision, but that judgment can come later on.

(No direct comment on this particular feature since I've not studied the implications)

/Daniel

To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/blink-dev/17d97061-3a99-45d4-b380-1786526d319c%40chromium.org.

David Bokan

unread,
Oct 9, 2019, 3:29:13 AM10/9/19
to blink-dev, Matthe...@microsoft.com
This sounds more like a UI change than a web platform change. I'm not sure the blink-dev process applies for this?

In addition to Daniel's point, this does have implications on web APIs in that we'd be decoupling the amount of scrolling from what's reported in the wheel events exposed to the page which could have compatibility and interop consequences; hence my request for a broader discussion.

For compatibility, this feature will change the value that Chromium surfaces to the event handlers for the mouse wheel event. Assuming we resolve the percentage to DOM_DELTA_PIXELS as they are currently surfaced today, we are presented with two problems:
1. The first is that the wheel event will bubble up to all elements that have an event listener for it. These elements will not know which scroller the delta will be applied to, and so the delta largely becomes meaningless.
2. Additionally, for websites that implement some custom UI which takes advantage of the wheel event but does not relate to scrolling at all (e.g. zooming on a map), a varying delta value would likely cause issues. The delta values it would receive would depend on whatever surrounding scrollers exist; and, if there are no surrounding scrollers, the delta will be based off of the window size which is likely something that is not desired.
Anecdotally, EdgeHTML implemented this feature in a similar fashion, except the percentage for the wheel event (but not the scroll) was always resolved against the window size. Even though this technically did not adhere to the spec and was inaccurate, we did not see any compatibility bugs due to this.

Note, I've seen this come up again in a proposal to make horizontal scrolling on RTL pages more natural: https://github.com/w3c/csswg-drafts/issues/4380. It seems like there's multiple good use cases for having the amount of scroll be dependent on the element that gets scrolled so having the delta be specified a priori doesn't make much sense in those cases. I'd be in favor of  loosening the spec text to allow UAs to scroll an amount different than what's reported in the wheel event (e.g. make the reported delta be "as-if" scrolling the documentElement or just an OS-dependent constant multiple). 
Reply all
Reply to author
Forward
0 new messages