Fractional scroll offsets and web compat risk

447 views
Skip to first unread message

Rick Byers

unread,
Dec 11, 2014, 11:46:04 AM12/11/14
to Yufeng Shen, Ian Vollick, Levi Weintraub, input-dev
Yufeng and I were discussing the other day what situations it's reasonable for JS to see fractional scroll offsets.  For example, he's found that dragging the scrollbar on low-dpi without any zooming going on will result in fractional scroll offsets being reported.  He pointed out that this is an accurate representation of what's happening (just like JS asking to set the scroll position based on some math), and will help us find bugs in other code handling fractions.

This blink-dev thread (below) has got me thinking that we should perhaps be more conservative to try to limit the web compat impact to scenarios where there is actually real benefit to getting the fractional scroll value.

So, for example, when handling input events or dragging the scroll bar on low-dpi unzoomed, we should perhaps ensure scrollTop always reports an integer.  But what about more subtle cases like JS explicitly setting a fractional scroll offset?  Do we want to go down the path of putting physical-pixel-snapping logic into blink?  Or perhaps the compositor should be involved - telling blink how the offset was ultimately snapped to a physical pixel?

Rick

---------- Forwarded message ----------
From: Rick Byers <rby...@chromium.org>
Date: Thu, Dec 11, 2014 at 11:37 AM
Subject: Re: [blink-dev] Re: Intent to Implement and Ship: Subpixel precision for clientWidth, offsetWidth, scrollTop et al
To: Boris Zbarsky <bzba...@mit.edu>
Cc: PhistucK <phis...@gmail.com>, blink-dev <blin...@chromium.org>


I think we're talking just about scrollTop/scrollLeft here.  We haven't enabled fractional values from offsetWidth et al. because that _does_ appear to be too web breaking.  getBoundingClientRect has returned the true fractional values in Chrome for a long time though.

It is really unfortunate that this change caused some breakage.  But I'm not convinced we have enough data yet to say it needs to be reverted.  Fractional scroll offsets during browser zoom have been in Chrome Canary since Sept 22nd, Beta since Oct 9th and Stable since Nov 18th, and this is the first / only issue we've heard of.  Compatibility is a tough tradeoff - there are no absolutes other than halting all development.  We rely on upfront due diligence for what's likely to be compatible, and getting enough feedback during Beta to warn of us any really problematic changes. This change was mentioned in the Chrome 39 beta blog post, and is covered in the intents tracking sheet.  If we had gotten this report during Beta we could have at least held off shipping to to stable for a milestone while the application in question was updated.  It's unlikely we would have aborted the attempt completely based on a single example though.

To see concretely how this change improves existing code, you can use this test page with browser zoom.  Notice how on Chrome 39 the red and green boxes stay lined up (although there can still be some lag while moving - that's a separate issue we're working on).  This code is doing the naive thing we see all over the web: setting a transform with the offset received from scrollTop.  Prior to this change in Chrome 39 you'd see it would often be one pixel off when at 200% zoom.  This example it designed to highlight the problems inherent in trying to synchronize effects with scrolling, but lots of real websites do things like this already, eg the Polymer scroll-header component.

The next step for us here is to start returning fractional scroll offsets in high-dpi cases as well as the existing browser zoom cases.  I'd love any feedback on how we can mitigate further compatibility risk here.  Unfortunately cases like this one where a scroll offset is passed over the network to some server which barfs on the fraction is not something we can directly search existing websites for.  We could, however, do something like load the top 1-million websites and scroll their main page with and without fractions and look for any differences in JS exceptions in the two cases.  Other thoughts?

Rick

On Thu, Dec 11, 2014 at 10:54 AM, Boris Zbarsky <bzba...@mit.edu> wrote:
On 12/11/14, 1:02 AM, PhistucK wrote:
This seems to only affect zoomed pages, or pages viewed on high device
pixel ratio ('retina' like) screens. Am I correct?

I can't speak for Blink, but in Gecko you would not be correct.  You can get fractional widths or heights pretty easily even when CSS and device px are the same size in Gecko.  Some simple examples:

1)  <div style="width: 90px">
      <div style="width: 25%">I'm fractional-width</div>
    </div>

2)  <div style="float: left">
      Some text whose width happens to be fractional due to
      subpixel glyph positioning.
    </div>

3)  <div style="font-size: 14px; line-height: 100px">
       Some <span style="font-size: 15px">text</span> which may have
       non-integer height once you're done baseline-aligning things.
    </div>

None of that answers your question about Blink fallout, I guess.

-Boris


Yufeng Shen

unread,
Dec 11, 2014, 1:44:38 PM12/11/14
to Rick Byers, Ian Vollick, Levi Weintraub, input-dev, Alexandre Elias
On Thu, Dec 11, 2014 at 11:45 AM, Rick Byers <rby...@chromium.org> wrote:
Yufeng and I were discussing the other day what situations it's reasonable for JS to see fractional scroll offsets.  For example, he's found that dragging the scrollbar on low-dpi without any zooming going on will result in fractional scroll offsets being reported.  He pointed out that this is an accurate representation of what's happening (just like JS asking to set the scroll position based on some math), and will help us find bugs in other code handling fractions.

This blink-dev thread (below) has got me thinking that we should perhaps be more conservative to try to limit the web compat impact to scenarios where there is actually real benefit to getting the fractional scroll value.


I feel this particular bug (their server side code is not expecting floating point scrollTop) is bound to happen because of the scrollTop API change.
So in some sense, being not conservative makes them fail fast while being conservative might limit impact but won't make the bug go away.

But again of course there would be other bugs along the road and I am supporting ruling out the cases where fractional scroll does not add much value,
which also makes my life easier.  This is similar to our discussion with Alex and Ian on the thread https://codereview.chromium.org/747903005/.

 
So, for example, when handling input events or dragging the scroll bar on low-dpi unzoomed, we should perhaps ensure scrollTop always reports an integer. 
But what about more subtle cases like JS explicitly setting a fractional scroll offset?  Do we want to go down the path of putting physical-pixel-snapping logic into blink?  Or perhaps the compositor should be involved - telling blink how the offset was ultimately snapped to a physical pixel?


Again in the spirit of my thoughts above, I think it is reasonable to gauge at the input side, e.g. only passing in integer scroll offset if on low-dpi.
But on the web API side, if we are pushing the standard to be using floating point for scrollTop(), shouldn't we  be fully committed to it ?

Rick Byers

unread,
Mar 18, 2015, 10:24:19 AM3/18/15
to Matt Gaunt, Yufeng Shen, Ian Vollick, Levi Weintraub, input-dev, Alexandre Elias
We're shipping fractional scroll offsets for high-dpi in M42.  I realized I forgot to get this mentioned in the M42 blog post.  We covered fractional scrollTop generally in M39 (when I changed the APIs - affecting browser zoom scenarios), but extending this to high-dpi scenarios might still catch some people by surprise (since it brings it to virtually ALL mobile use cases). The offsets may not be able to 

We haven't seen any compat issues yet, but I'm sure there's at least a couple out there somewhere.  I whipped up a quick and dirty G+ / Twitter post last night (though it could probably use some better explaining, maybe an animated GIF showing the difference in practice or something).  Matt, should we do anything more?

Note that I just noticed a potential issue with scroll offsets not being snapped to device pixels - not sure if it matters or not, but I'd like to understand the behavior we're seeing.

Rick

Rick Byers

unread,
Mar 18, 2015, 11:10:18 AM3/18/15
to Matt Gaunt, Yufeng Shen, aero...@chromium.org, Ian Vollick, Levi Weintraub, input-dev, Alexandre Elias
+aerotwist@ since Matt is out of the office this week.

On Wed, Mar 18, 2015 at 10:23 AM, Rick Byers <rby...@chromium.org> wrote:
We're shipping fractional scroll offsets for high-dpi in M42.  I realized I forgot to get this mentioned in the M42 blog post.  We covered fractional scrollTop generally in M39 (when I changed the APIs - affecting browser zoom scenarios), but extending this to high-dpi scenarios might still catch some people by surprise (since it brings it to virtually ALL mobile use cases). The offsets may not be able to 

Not sure what I was planning on saying here - ignore this last sentence.

Rick Byers

unread,
Mar 18, 2015, 7:03:27 PM3/18/15
to Matt Gaunt, Yufeng Shen, aero...@chromium.org, Ian Vollick, Levi Weintraub, input-dev, Alexandre Elias
We just decided (for unrelated reasons) to postpone shipping this to stable - probably until Chrome 44.  The questions still stand but we have bought ourselves more time.  Yufeng, let's make sure we get something into the beta blog post for the release this re-ships in.


Paul Lewis

unread,
Mar 19, 2015, 5:50:23 AM3/19/15
to Rick Byers, Matt Gaunt, Yufeng Shen, Ian Vollick, Levi Weintraub, input-dev, Alexandre Elias
In general I'm all for fractional values, since pixel-rounding issues can be a nuisance. That said, I don't know how breaking a change it would be, either. The only suggestion I can make is that Matt or I do some additional advocacy to test the developer sentiment and, if nothing else, record the plan on HTML5 Rocks or similar.
Reply all
Reply to author
Forward
0 new messages