Intent to Implement and Ship: Subpixel precision for clientWidth, offsetWidth, scrollTop et al

2,379 views
Skip to first unread message

Emil A Eklund

unread,
Apr 7, 2014, 6:58:43 PM4/7/14
to blink-dev
Primary eng/PM emails
e...@chromium.org

Spec
http://www.w3.org/TR/cssom-view/#scrolloptionsvertical

Summary
The latest draft of the CSS OM spec changed the type for a number of
Element, HTMLElement and textRange properties from long to float.

Specifically the following properties:
Element::clientHeight
Element::clientWidth
Element::clientLeft
Element::clientTop
Element::scrollTop
Element::scrollLeft
Element::scrollWidth
Element::scrollHeight
HTMLElement::offsetWidth
HTMLElement::offsetHeight
HTMLElement::offsetTop
HTMLElement::offsetLeft

Those are now specified to return the full precision value, similarly
to Element::getClientRects and Element::getBoundingClientRect.

Motivation
IE has been supporting this on an opt-in basis since version 10 and
many complex web apps requires higher precision than rounded int
values. For offsetWidth and friends getClientRects is a viable
alternative but for scrollTop/Left/Width/Height no high precision
alternative exists.

Compatibility Risk
Firefox: No public signals
Internet Explorer: No public signals
Safari: No public signals
Web developers: Positive

This could have compatibility issues as we are changing the data
type for existing properties. Some websites may depend on the values
being integers.

Ongoing technical constraints
Cannot be controlled by runtime enabled feature with our existing
implementation as it modifies existing properties.

Will this feature be supported on all five Blink platforms (Windows, Mac, Linux,
Chrome OS, and Android)?
Yes

OWP launch tracking bug
http://www.w3.org/TR/cssom-view/#scrolloptionsvertical

Entry in Chromium Dashboard
http://www.chromestatus.com/admin/features/edit/5497402177880064

Requesting approval to ship?
Yes

Erik Arvidsson

unread,
Apr 7, 2014, 7:44:21 PM4/7/14
to Emil A Eklund, blink-dev
This is awesome.

LGTM
--
erik


Ojan Vafai

unread,
Apr 7, 2014, 7:46:34 PM4/7/14
to Erik Arvidsson, Emil A Eklund, blink-dev
LGTM. Hopefully it will be web compatible.

TAMURA, Kent

unread,
Apr 7, 2014, 7:47:35 PM4/7/14
to Ojan Vafai, Erik Arvidsson, Emil A Eklund, blink-dev
LGTM2

--
TAMURA Kent
Software Engineer, Google


Eric Seidel

unread,
Apr 7, 2014, 8:47:20 PM4/7/14
to Emil A Eklund, blink-dev
I like the idea. Curious what IE's opt-in/opt-out method is like and
if we are likely to need to implement it?

I assume the plan is to ship this to Beta and see if anyone screams
and unship if it's web-incompatible (possibly later shipping opt-in
like IE did?)

This definitely seems like it is both good for the future of the web
as well as definitely not any more of a burden on Blink's complexity,
so LGTM.

Emil A Eklund

unread,
Apr 7, 2014, 8:50:11 PM4/7/14
to Eric Seidel, blink-dev
On Mon, Apr 7, 2014 at 5:47 PM, Eric Seidel <ese...@chromium.org> wrote:
> I like the idea. Curious what IE's opt-in/opt-out method is like and
> if we are likely to need to implement it?

They implemented support for this before the standard was updated. It
is controlled by the document.msCSSOMElementFloatMetrics property.

http://blogs.msdn.com/b/ie/archive/2012/02/17/sub-pixel-rendering-and-the-css-object-model.aspx?Redirected=true


> I assume the plan is to ship this to Beta and see if anyone screams
> and unship if it's web-incompatible (possibly later shipping opt-in
> like IE did?)

Correct. That is the plan.

Simon Pieters

unread,
Apr 8, 2014, 3:57:27 AM4/8/14
to Eric Seidel, Emil A Eklund, blink-dev
An alternative to IE's opt-in could be to provide separate APIs that give
sub-pixel precision, and revert the APIs that turned out to not be Web
compatible to return integers. I think that would be more flexible than a
document-wide switch since different scripts can use either API without
affecting the behavior of other scripts.

--
Simon Pieters
Opera Software

Anne van Kesteren

unread,
Apr 8, 2014, 1:01:01 PM4/8/14
to Erik Arvidsson, Emil A Eklund, blink-dev
On Mon, Apr 7, 2014 at 4:44 PM, Erik Arvidsson <a...@chromium.org> wrote:
> This is awesome.

If we want to make layout more asynchronous and expose more of it
asynchronously (eg the box tree in a worker) does it really make sense
to improve getters that require synchronous layout?


--
http://annevankesteren.nl/

Emil A Eklund

unread,
Apr 8, 2014, 1:03:58 PM4/8/14
to Anne van Kesteren, Erik Arvidsson, blink-dev
I agree that long term it makes sense to have a more asynchronous API,
for now though there is no way to get precise values for some of these
properties which this change (and the spec change) tries to solve.

Elliott Sprehn

unread,
Apr 8, 2014, 1:04:34 PM4/8/14
to Anne van Kesteren, Erik Arvidsson, Emil A Eklund, blink-dev
On Tue, Apr 8, 2014 at 10:01 AM, Anne van Kesteren <ann...@annevk.nl> wrote:
Any type of Box Tree API (which I'm not entirely convinced should be exposed at all), or exposing the rendering system to workers, is going to take years to design and implement. We shouldn't stop improving what already exists while that happens.

- E

Anne van Kesteren

unread,
Apr 8, 2014, 1:10:38 PM4/8/14
to Elliott Sprehn, Erik Arvidsson, Emil A Eklund, blink-dev
On Tue, Apr 8, 2014 at 10:04 AM, Elliott Sprehn <esp...@chromium.org> wrote:
> Any type of Box Tree API (which I'm not entirely convinced should be exposed
> at all), or exposing the rendering system to workers, is going to take years
> to design and implement. We shouldn't stop improving what already exists
> while that happens.

No disagreement there, but should we offer promise-based APIs or keep
improving the synchronous variants? The longer we stick with
synchronous APIs for layout, the harder it will be to get everyone to
change their mindset down the road, if that is even feasible at that
point.


--
http://annevankesteren.nl/

Elliott Sprehn

unread,
Apr 8, 2014, 1:13:58 PM4/8/14
to Anne van Kesteren, Erik Arvidsson, Emil A Eklund, blink-dev
Oh I see, I actually think it would be much better to expose a getBoxMetrics() => Promise<BoxMetrics> API for getting height/width/scroll offsets and that's resolved at raf timing instead of improving offsetFoo APIs which have strange and surprising behavior unless we think that making them return floats will improve existing content.

- E 

Rick Byers

unread,
Apr 8, 2014, 2:20:17 PM4/8/14
to Elliott Sprehn, Anne van Kesteren, Erik Arvidsson, Emil A Eklund, blink-dev
I'm very anxious to get fractional scroll offsets as it's essential for high-quality implementations of certain scroll-linked effects (hidey bars, pull-to-refresh, etc.).  Do you think we'd also want a promise-based API for scrollTop/scrollLeft?  The cases I'm concerned with would access these properties from a 'scroll' event handler, so it might be a little weird (and potentially wasteful) to access them via a Promise.  We could of course add properties to the scroll event object instead.

We should also keep the migration cost in mind.  For the specific case of scrollTop/Left being read from 'scroll' handlers, if we can show it's sufficiently compatible, I think it would be better to update the existing API since that would immediately benefit a lot of existing code where there'd be no benefit to forcing the developers to use a new API instead.

Perhaps we should separate the scroll offset case from the box metrics case?

Rick

Alex Russell

unread,
Apr 8, 2014, 2:24:12 PM4/8/14
to Rick Byers, Elliott Sprehn, Anne van Kesteren, Erik Arvidsson, Emil A Eklund, blink-dev
I don't agree with Anne's framing: it's not either/or. We should make this improvement while planning for the async future. I'm excited about a better async box API, but it should not block this work.

LGTM.


To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.

Antonio Gomes

unread,
Apr 10, 2014, 6:21:25 PM4/10/14
to Alex Russell, Rick Byers, Elliott Sprehn, Anne van Kesteren, Erik Arvidsson, Emil A Eklund, blink-dev
I believe this is a progression. All in all, it would allow Blink to
get rid of FIXMEs like:

void HTMLBodyElement::setScrollLeft(int scrollLeft)
{
Document& document = this->document();
(...)
if (render->hasOverflowClip()) {
// FIXME: Investigate how are other browsers casting to
int (rounding, ceiling, ...).
render->setScrollLeft(static_cast<int>(scrollLeft *
render->style()->effectiveZoom()));
(...)
}

Btw, what is the code review URL?

Cheers,
--
--Antonio Gomes

Ojan Vafai

unread,
Apr 10, 2014, 6:55:56 PM4/10/14
to Elliott Sprehn, Anne van Kesteren, Erik Arvidsson, Emil A Eklund, blink-dev
I would love for someone to come up with a good promise-based API and I like the idea of giving carrots for developers to use the right thing. I have some concerns in this case:
1. I believe there's likely a lot of existing content that will benefit from making this change without needing to explicitly be modified to work.
2. I have yet to see a compelling proposal for a promise-based API that actually works well. If we wait until rAF time, we'll still need to do two synchronous layouts at rAF time (one for getting the metrics and then one for doing the actual layout post rAF callbacks). Two layouts is obviously better than the layout thrashing you get today. But then, what happens if you query getBoxMetrics during a getBoxMetrics or rAF callback? Does it wait for the next rAF? If not, then you now have same problem all over again. If yes, it will be hard to write code that doesn't miss a frame.

I support doing *something* here and would love for someone to make a well thought out proposal to the appropriate standards body. If we can get agreement on a design, I think Blink would likely make a priority of implementing it. This is definitely something we care about.

In the meantime, my LGTM stands for making these properties return floats if doing so is web compatible.

Ojan Vafai

unread,
Apr 10, 2014, 11:07:51 PM4/10/14
to Elliott Sprehn, Robert O'Callahan, Anne van Kesteren, Erik Arvidsson, Emil A Eklund, blink-dev
Incidentally, Mozilla appears to be implementing new sync APIs. These seem like better targets for adding a promise-based API. Although, again, it's not clear to me that a promised-based API actually works.

Robert O'Callahan

unread,
Apr 10, 2014, 11:59:36 PM4/10/14
to Ojan Vafai, Elliott Sprehn, Anne van Kesteren, Erik Arvidsson, Emil A Eklund, blink-dev
On Fri, Apr 11, 2014 at 3:07 PM, Ojan Vafai <oj...@chromium.org> wrote:
Incidentally, Mozilla appears to be implementing new sync APIs. These seem like better targets for adding a promise-based API. Although, again, it's not clear to me that a promised-based API actually works.


Note that these APIs represent a consensus reached on www-style last year. I didn't just make them up :-). We could add async versions of these as well, but like you I'm unconvinced they'd actually be useful. If someone comes up with a good case, sure.

Regarding the original "intent to implement" here, the "offset" properties are a real mess and they're obsoleted by getBoxQuads/convert*FromNode so I wouldn't bother changing their behavior in any way (and plan not to in Firefox). The scroll* and client* properties don't map exactly to anything currently defined in GeometryUtils, so making them subpixel-aware might make sense.

Although, to facilitate coordinate versions it might be a good idea to extend GeometryUtils to cover the use-cases for scroll* and client* too. We could do that by defining two new BoxTypes, e.g. "scrollport" for the rectangle inside the scrollbars (obsoleting client*) and "scrolled" for the rectangle of the scrolled content (obsoleting scroll*).

Rob
--
Jtehsauts  tshaei dS,o n" Wohfy  Mdaon  yhoaus  eanuttehrotraiitny  eovni le atrhtohu gthot sf oirng iyvoeu rs ihnesa.r"t sS?o  Whhei csha iids  teoa stiheer :p atroa lsyazye,d  'mYaonu,r  "sGients  uapr,e  tfaokreg iyvoeunr, 'm aotr  atnod  sgaoy ,h o'mGee.t"  uTph eann dt hwea lmka'n?  gBoutt  uIp  waanndt  wyeonut  thoo mken.o w 

Ojan Vafai

unread,
Apr 11, 2014, 1:12:19 PM4/11/14
to Robert O'Callahan, Elliott Sprehn, Anne van Kesteren, Erik Arvidsson, Emil A Eklund, blink-dev
On Thu, Apr 10, 2014 at 8:59 PM, Robert O'Callahan <rob...@ocallahan.org> wrote:
On Fri, Apr 11, 2014 at 3:07 PM, Ojan Vafai <oj...@chromium.org> wrote:
Incidentally, Mozilla appears to be implementing new sync APIs. These seem like better targets for adding a promise-based API. Although, again, it's not clear to me that a promised-based API actually works.


Note that these APIs represent a consensus reached on www-style last year. I didn't just make them up :-).

Email is hard. I didn't mean to imply that Mozilla's doing anything wrong. Just that, if Anne wants to push for async APIs, getBoxQuads/convert*FromNode might be a better place to focus that attention.
 
Regarding the original "intent to implement" here, the "offset" properties are a real mess and they're obsoleted by getBoxQuads/convert*FromNode so I wouldn't bother changing their behavior in any way (and plan not to in Firefox). The scroll* and client* properties don't map exactly to anything currently defined in GeometryUtils, so making them subpixel-aware might make sense.

That's fair. I still think it's valuable because of existing content that will work better on hidpi devices. Also because many web developers will continue using the offset* properties for the forseeable future and many of them likely won't notice that their animations are slightly jittery, or even if they do, they won't identify subpixel as the root cause. It's a subtle thing and requires a solid understanding of the platform.

Robert O'Callahan

unread,
Apr 11, 2014, 6:37:56 PM4/11/14
to Ojan Vafai, Elliott Sprehn, Anne van Kesteren, Erik Arvidsson, Emil A Eklund, blink-dev
On Sat, Apr 12, 2014 at 5:12 AM, Ojan Vafai <oj...@chromium.org> wrote:
That's fair. I still think it's valuable because of existing content that will work better on hidpi devices. Also because many web developers will continue using the offset* properties for the forseeable future and many of them likely won't notice that their animations are slightly jittery, or even if they do, they won't identify subpixel as the root cause. It's a subtle thing and requires a solid understanding of the platform.

Do you have a characterization of the sort of content that will get automatically better vs the sort of content that will break?

Adam Barth

unread,
Apr 11, 2014, 7:00:09 PM4/11/14
to rob...@ocallahan.org, oj...@chromium.org, esp...@chromium.org, ann...@annevk.nl, a...@chromium.org, e...@google.com, blin...@chromium.org
On Fri Apr 11 2014 at 3:37:59 PM, Robert O'Callahan <rob...@ocallahan.org> wrote:
On Sat, Apr 12, 2014 at 5:12 AM, Ojan Vafai <oj...@chromium.org> wrote:
That's fair. I still think it's valuable because of existing content that will work better on hidpi devices. Also because many web developers will continue using the offset* properties for the forseeable future and many of them likely won't notice that their animations are slightly jittery, or even if they do, they won't identify subpixel as the root cause. It's a subtle thing and requires a solid understanding of the platform.

Do you have a characterization of the sort of content that will get automatically better vs the sort of content that will break?

I'm not sure how clean a characterization it is, but we've recently written a bunch of exploratory code that creates scroll-linked effects like hidey bars by updating the transform on a number of elements to a value computed from the scroll offset.  If that code receives a subpixel floating point number, it will do the same math and set the appropriate subpixel transform without any modification.

Adam

Nat Duca

unread,
Apr 11, 2014, 7:30:45 PM4/11/14
to Adam Barth, Robert O'Callahan, Ojan Vafai, Elliott Sprehn, Anne van Kesteren, a...@chromium.org, Emil A Eklund, blink-dev
I'm not sure how clean a characterization it is, but we've recently written a bunch of exploratory code that creates scroll-linked effects like hidey bars by updating the transform on a number of elements to a value computed from the scroll offset.  If that code receives a subpixel floating point number, it will do the same math and set the appropriate subpixel transform without any modification.

The counterpoint being that without this precision, then the object being transformed will appear to jitter at a subpixel as the main content scrolls. For stuff like parallax this might not be noticeable, but for the hidey bars where they're actually designed to feel "responsive" to the finger, the effect can be jarring.

Rick Byers

unread,
Apr 11, 2014, 7:46:35 PM4/11/14
to Nat Duca, blink-dev, Anne van Kesteren, Elliott Sprehn, Robert O'Callahan, Adam Barth, Ojan Vafai, a...@chromium.org, Emil A Eklund

As for the other half of the question (what will break), we don't know.  I have trouble imagining anything too common, but that's what this intent is all about: let's try and see what happens.  Of course we'll discuss the risk of breakage here once we find concrete examples.

Alex Russell

unread,
Apr 11, 2014, 7:51:14 PM4/11/14
to Ojan Vafai, Robert O'Callahan, Elliott Sprehn, Anne van Kesteren, Erik Arvidsson, Emil A Eklund, blink-dev
On Fri, Apr 11, 2014 at 10:12 AM, Ojan Vafai <oj...@chromium.org> wrote:
On Thu, Apr 10, 2014 at 8:59 PM, Robert O'Callahan <rob...@ocallahan.org> wrote:
On Fri, Apr 11, 2014 at 3:07 PM, Ojan Vafai <oj...@chromium.org> wrote:
Incidentally, Mozilla appears to be implementing new sync APIs. These seem like better targets for adding a promise-based API. Although, again, it's not clear to me that a promised-based API actually works.


Note that these APIs represent a consensus reached on www-style last year. I didn't just make them up :-).

Email is hard. I didn't mean to imply that Mozilla's doing anything wrong. Just that, if Anne wants to push for async APIs, getBoxQuads/convert*FromNode might be a better place to focus that attention.

I'm for that as well. New APIs that return style values should be async.
 
 
Regarding the original "intent to implement" here, the "offset" properties are a real mess and they're obsoleted by getBoxQuads/convert*FromNode so I wouldn't bother changing their behavior in any way (and plan not to in Firefox). The scroll* and client* properties don't map exactly to anything currently defined in GeometryUtils, so making them subpixel-aware might make sense.

That's fair. I still think it's valuable because of existing content that will work better on hidpi devices. Also because many web developers will continue using the offset* properties for the forseeable future and many of them likely won't notice that their animations are slightly jittery, or even if they do, they won't identify subpixel as the root cause. It's a subtle thing and requires a solid understanding of the platform.

To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.

Robert O'Callahan

unread,
Apr 12, 2014, 4:47:26 PM4/12/14
to Adam Barth, Ojan Vafai, Elliott Sprehn, Anne van Kesteren, Erik Arvidsson, Emil A Eklund, blink-dev
That sounds reasonable. But do such scripts use anything other than scrollLeft/scrollTop?

Robert O'Callahan

unread,
Apr 12, 2014, 4:48:18 PM4/12/14
to Alex Russell, Ojan Vafai, Elliott Sprehn, Anne van Kesteren, Erik Arvidsson, Emil A Eklund, blink-dev
On Sat, Apr 12, 2014 at 11:51 AM, Alex Russell <sligh...@google.com> wrote:
I'm for that as well. New APIs that return style values should be async.

I don't agree with that as a universal requirement but we should have that discussion on www-style please.

Rob
--

Adam Barth

unread,
Apr 13, 2014, 2:23:06 AM4/13/14
to rob...@ocallahan.org, oj...@chromium.org, esp...@chromium.org, ann...@annevk.nl, a...@chromium.org, e...@google.com, blin...@chromium.org
On Sat Apr 12 2014 at 1:47:26 PM, Robert O'Callahan <rob...@ocallahan.org> wrote:
On Sat, Apr 12, 2014 at 11:00 AM, Adam Barth <aba...@google.com> wrote:
On Fri Apr 11 2014 at 3:37:59 PM, Robert O'Callahan <rob...@ocallahan.org> wrote:
On Sat, Apr 12, 2014 at 5:12 AM, Ojan Vafai <oj...@chromium.org> wrote:
That's fair. I still think it's valuable because of existing content that will work better on hidpi devices. Also because many web developers will continue using the offset* properties for the forseeable future and many of them likely won't notice that their animations are slightly jittery, or even if they do, they won't identify subpixel as the root cause. It's a subtle thing and requires a solid understanding of the platform.

Do you have a characterization of the sort of content that will get automatically better vs the sort of content that will break?

I'm not sure how clean a characterization it is, but we've recently written a bunch of exploratory code that creates scroll-linked effects like hidey bars by updating the transform on a number of elements to a value computed from the scroll offset.  If that code receives a subpixel floating point number, it will do the same math and set the appropriate subpixel transform without any modification.

That sounds reasonable. But do such scripts use anything other than scrollLeft/scrollTop?

Looks like the two scripts I wrote use scrollTop, but I probably just picked the first thing that worked.

Adam

Message has been deleted

Emil A Eklund

unread,
Jun 19, 2014, 1:11:08 PM6/19/14
to blink-dev
Due to breaking a number of high profile sites we've been forced to
revert this change. I plan to try again in M38.

Christian Biesinger

unread,
Jun 19, 2014, 3:19:14 PM6/19/14
to Emil A Eklund, blink-dev
Can you share some details on how this caused sites to break (and how
M38 will fix it)? In what way to sites expect integer return values?

Just curious. Thanks!

-christian

Emil A Eklund

unread,
Jun 19, 2014, 3:31:54 PM6/19/14
to Christian Biesinger, blink-dev
On Thu, Jun 19, 2014 at 12:19 PM, Christian Biesinger
<cbies...@chromium.org> wrote:
> Can you share some details on how this caused sites to break (and how
> M38 will fix it)? In what way to sites expect integer return values?

Bugs 378052, 382889, 380146, and 386500 have details. Evangelism will
be needed to mitigate the issues.

Simon Pieters

unread,
Aug 5, 2014, 9:57:36 AM8/5/14
to Christian Biesinger, 'Emil A Eklund' via blink-dev, Emil A Eklund
What is the status on this? Did you learn which APIs in particular broke?

Rick Byers

unread,
Sep 23, 2014, 11:03:07 AM9/23/14
to Simon Pieters, Christian Biesinger, 'Emil A Eklund' via blink-dev, Emil A Eklund, miletus
Sorry for the long delay on this - mostly we were waiting for websites with known issues to be updated.  There are some details here about the specific issues we hit.

We've recently decided to try shipping just the fractional scroll offset support (scrollTop/scrollLeft etc.) without shipping fractional positioning/sizing (offsetTop, scrollHeight, etc.).  I've just landed a CL that exposes fractional scroll offsets to JS (http://crbug.com/373731), currently visible only in browser zoom scenarios.  miletus@ is in the process of teaching blink about fractional scroll offsets for high-dpi and pinch-zoom scenarios (http://crbug.com/414283).

Personally I'm not sure how important making the positioning/sizing properties fractional is (since we have getBoundingClientRect).  I think we'll come back to that once we've learn whether fractional scroll offsets can ship on their own.  Please let me know if anyone sees any issues they think could be do to fractional scrollTop/left values.

Rick

Dave Methvin

unread,
Dec 10, 2014, 3:30:08 PM12/10/14
to blin...@chromium.org, sim...@opera.com, cbies...@chromium.org, e...@google.com, mil...@chromium.org
Just FYI, even the scrollTop change does appear to break some code: https://github.com/jquery/api.jquery.com/issues/608

Also FYI, jQuery is strongly considering a switch from .offsetTop/Width etc to getBoundingClientRect with 3.0 (early 2015) which would return fractional values there at the expense of performance (gBCR is much slower). We decided we had to make the change in a major-point release because in the past we looked at this and thought there would be a lot of breakage in older code that expects integer values. Obviously web devs can opt in to upgrading their site to jQuery 3.0 but not to a Chrome update, so perhaps you would want to wait for the fallout of that release?
Message has been deleted

mich...@gmail.com

unread,
Dec 10, 2014, 4:01:19 PM12/10/14
to blin...@chromium.org, e...@google.com
Implementing this broke my client's site,likely leading to lots of lost and refunded revenue and possibly costing people their jobs, and worse. Many careers are dependent on my client's site.


Changing the type on an existing variable like this is a terrible thing to do. Not everyone plays around in type-unsafe languages, and this bug was extremely difficult for us to find. You should have used a new property or a supplemental value for this to preserve existing functionality. 

Please don't follow MS' lead by playing fast and loose with standards. Doing so hurts people in real, tangible ways, much more than just code.

On Monday, April 7, 2014 3:58:43 PM UTC-7, Emil A Eklund wrote:
Primary eng/PM emails
  e...@chromium.org

Spec
  http://www.w3.org/TR/cssom-view/#scrolloptionsvertical

Summary
  The latest draft of the CSS OM spec changed the type for a number of
Element, HTMLElement and textRange properties from long to float.

Specifically the following properties:
Element::clientHeight
Element::clientWidth
Element::clientLeft
Element::clientTop
Element::scrollTop
Element::scrollLeft
Element::scrollWidth
Element::scrollHeight
HTMLElement::offsetWidth
HTMLElement::offsetHeight
HTMLElement::offsetTop
HTMLElement::offsetLeft

Those are now specified to return the full precision value, similarly
to Element::getClientRects and Element::getBoundingClientRect.

Motivation
  IE has been supporting this on an opt-in basis since version 10 and
many complex web apps requires higher precision than rounded int
values. For offsetWidth and friends getClientRects is a viable
alternative but for scrollTop/Left/Width/Height no high precision
alternative exists.

Compatibility Risk
  Firefox: No public signals
  Internet Explorer: No public signals
  Safari: No public signals
  Web developers: Positive

  This could have compatibility issues as we are changing the data
type for existing properties. Some websites may depend on the values
being integers.

Ongoing technical constraints
  Cannot be controlled by runtime enabled feature with our existing
implementation as it modifies existing properties.

Will this feature be supported on all five Blink platforms (Windows, Mac, Linux,
Chrome OS, and Android)?
  Yes

OWP launch tracking bug
  http://www.w3.org/TR/cssom-view/#scrolloptionsvertical

Entry in Chromium Dashboard
  http://www.chromestatus.com/admin/features/edit/5497402177880064

Requesting approval to ship?
  Yes

Matthew Menke

unread,
Dec 10, 2014, 4:31:21 PM12/10/14
to blin...@chromium.org, e...@google.com, mich...@gmail.com
Worth noting this is not a case of the Chromium project unilaterally changing code behavior to violate standards, this is the case of the standard being changed by the w3c.

Rick Byers

unread,
Dec 10, 2014, 5:08:20 PM12/10/14
to Matthew Menke, blink-dev, Emil A Eklund, mich...@gmail.com
I'm sorry to hear that this change broke your site.  We tried hard to look for examples of sites / code broken by this change and couldn't find any, and so didn't feel it was worth the extra complexity on the platform to push for a new set of parallel APIs (element.scrollTopDouble).  Also we've found a number of sites whose behavior/performance improves automatically as a result of getting fractions.

Regardless, blink-dev isn't really the right forum for this.  This is a question for the CSSWG since the standard has been updated to reflect this change: http://www.w3.org/TR/cssom-view/#extensions-to-the-window-interface.  If you're interested in continuing this debate then please start a thread on www-...@w3.org and I'll be happy to represent Chromium/blink there.

Rick

Boris Zbarsky

unread,
Dec 10, 2014, 5:12:48 PM12/10/14
to blink-dev
On 12/10/14, 4:31 PM, Matthew Menke wrote:
> Worth noting this is not a case of the Chromium project unilaterally
> changing code behavior to violate standards, this is the case of the
> standard being changed by the w3c.

Well, sort of. It's a case of a spec editor (who happens to be employed
by a company that uses Blink, fwiw) suggesting the change and putting it
in the spec draft, in spite of pretty much every other rendering engine
saying they're not going to ship it because it's almost guaranteed to
not be web compatible...

-Boris

mich...@gmail.com

unread,
Dec 10, 2014, 5:38:51 PM12/10/14
to blin...@chromium.org, mme...@google.com, e...@google.com, mich...@gmail.com
Well, the doc you point to is a "working draft". It says explicitly in the header:

Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

So this means the Chromium team is implementing working drafts that have not been adopted, and then expecting those of us who maintain sites and write code to follow the Chromium lead, not the W3C lead? Please clarify.

-Michael

Mike Sherov

unread,
Dec 10, 2014, 10:39:52 PM12/10/14
to mich...@gmail.com, blin...@chromium.org, mme...@google.com, e...@google.com
Boris,

We should bring this up at the next CSSWG meeting. I agree with you that changing scrollTop/offsetWidth/offsetHeight is not web compatible and we should revert the spec change.

Dave,
I would guess that gBRC is just as slow as offsetWidth/offsetTop, no? Both (and really any width measurement) require layout recalcs. Do you have a jsperf or something to show? When I looked into this for jQuery, I found gBRC to do a suitable replacement but didn't have the time to implement. 
To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.


--
Mike Sherov


Dave Methvin

unread,
Dec 10, 2014, 11:09:31 PM12/10/14
to blin...@chromium.org, mich...@gmail.com, mme...@google.com, e...@google.com

On Wednesday, December 10, 2014 10:39:52 PM UTC-5, Mike Sherov wrote:
Boris,

We should bring this up at the next CSSWG meeting. I agree with you that changing scrollTop/offsetWidth/offsetHeight is not web compatible and we should revert the spec change.


Agreed. Fractional values for scrollTop or others are likely to break existing web pages, which is why we haven't yet made that change in jQuery and were saving it for a major-point release. I didn't notice Chrome had tried this earlier in the year until it had been reverted or I would have followed it more closely.  http://bugs.jquery.com/ticket/9628#comment:18

Dave,
I would guess that gBRC is just as slow as offsetWidth/offsetTop, no? Both (and really any width measurement) require layout recalcs. Do you have a jsperf or something to show? When I looked into this for jQuery, I found gBRC to do a suitable replacement but didn't have the time to implement. 

Here is a jsperf supplied by one of the PRs we got: http://jsperf.com/offsetwidth-vs-getclientrects-vs-getboundingclientrect

Odds are that the difference there isn't really so big after factoring in the odds of a style recalc and possible layout.

To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+unsubscribe@chromium.org.


--
Mike Sherov


PhistucK

unread,
Dec 11, 2014, 1:02:59 AM12/11/14
to Rick Byers, Matthew Menke, blink-dev, Emil A Eklund, mich...@gmail.com
This seems to only affect zoomed pages, or pages viewed on high device pixel ratio ('retina' like) screens. Am I correct?
This breakage is suggested to be high (or perhaps there are a few vocal users?). This is interesting - how come? Mobile?
A lot of mobile users on api.jquery.com?


PhistucK

To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.

Simon Pieters

unread,
Dec 11, 2014, 4:58:40 AM12/11/14
to blink-dev, Boris Zbarsky
On Wed, 10 Dec 2014 23:10:24 +0100, Boris Zbarsky <bzba...@mit.edu> wrote:

> On 12/10/14, 4:31 PM, Matthew Menke wrote:
>> Worth noting this is not a case of the Chromium project unilaterally
>> changing code behavior to violate standards, this is the case of the
>> standard being changed by the w3c.
>
> Well, sort of. It's a case of a spec editor (who happens to be employed
> by a company that uses Blink, fwiw) suggesting the change and putting it
> in the spec draft,

Yes.

> in spite of pretty much every other rendering engine saying they're not
> going to ship it because it's almost guaranteed to not be web
> compatible...

Gecko tried implementing it for some properties before the spec was
changed and reverted because some sites broke. IE shipped it without
opt-in for MouseEvent coordinates, and with an opt-in for other APIs, also
before the spec change. I asked which properties broke and which sites
broke, but that was not really known. I don't recall anyone saying "we
will not ship this", but more "is this Web-compatible?". Blink being the
third vendor to experiment with shipping this is trying to finding out
what is Web-compatible and what is not, so that we can figure out the best
path forward. Assuming that everything will break and have duplicate APIs
for everything (or require an opt-in) would be safe but it wouldn't be
pretty and it wouldn't improve existing pages that use the old APIs and
don't break.

I'm sorry for the negative consequences of the experiment.

If we have enough experience at this point to say which properties need to
return integers for Web compat, we should update the spec to reflect that.
If so, please take it to www-style.

Relevant spec bug https://www.w3.org/Bugs/Public/show_bug.cgi?id=24159
Message has been deleted

mich...@gmail.com

unread,
Dec 11, 2014, 10:42:13 AM12/11/14
to blin...@chromium.org, rby...@chromium.org, mme...@google.com, e...@google.com, mich...@gmail.com
My client delivers content in an iFrame-based UI, and users often zoom on the content for readability and accessibility. We experienced problems related to tracking student interaction and navigation through the content. Pixel values are sent to a web service which logs student time and determines whether additional content can be "unlocked", and that service assumed the values would be integers. We saw an uptick in server issues but were not able to quickly correlate this with reported client issues from users. 

Most of the client's customers are on corporate desktops. The content is not generally mobile-friendly, so anyone using the site on a mobile browser is almost certainly zooming on the content. However, the issue was not isolated to mobile users.

The bug started showing on our logs in late October, and occurrence increased rapidly and markedly through November, into December. This corresponds with our natural cycle of user interaction, so that would mask associations with a technology upgrade (browser or OS). The issues they were experiencing were also similar to known bugs and incompatibilities in our client, code, which further masked the source.

It was extremely difficult for us to track as we did not see a common thread between clients who were experiencing issues with accessing content. They seemed to come from a variety of browsers and platforms and were accessing all types of content (traditional HTML, HTML5, PDF, Flash, etc...). I believe that many reported issues were addressed by simply having users change browsers, so there weren't initially a lot of escalations.

One reason my client may be early to identify this issue is that we have a very personalized support process, and students experiencing problems are encouraged to call our support personnel. I sit next to support, so I hear the calls and can react quickly, as we are often responding to unanticipated browser changes affecting client code. So our response time is pretty quick for an online content provider. Usually these issues are obvious. This one manifested in a much more subtle yet pervasive way than a typical incompatibility introduced by specific new browsers.

Boris Zbarsky

unread,
Dec 11, 2014, 10:54:31 AM12/11/14
to PhistucK, blink-dev
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

Rick Byers

unread,
Dec 11, 2014, 11:39:08 AM12/11/14
to Boris Zbarsky, PhistucK, blink-dev
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

mich...@gmail.com

unread,
Dec 11, 2014, 11:48:04 AM12/11/14
to blin...@chromium.org, bzba...@mit.edu, phis...@gmail.com
Very sensible, Rick. We rely on jQuery to insulate us as much as possible from ongoing changes in W3C specs and browsers like this, and this issue manifested for us through jQuery's scrollTop() API. I believe your approach is correct for Chromium, and that developers who rely on jQuery for insulation need to make sure we're engaged with jQuery to keep API's compatible as browser functionality improves. 

Ultimately, this change will improve life for our users as they get better zooming behavior in high resolution contexts.

Rick Byers

unread,
Dec 11, 2014, 11:58:33 AM12/11/14
to mich...@gmail.com, blink-dev, Boris Zbarsky, PhistucK Productions
Thank you Michael!

This thread is a good reminder about how thoughtful we need to be of the risks when making any web-exposed change.  We care deeply about making developers more productive - so any situation like this is a (relatively small) step in the wrong direction. Thanks for providing details of your experience.  For each person that does, I'm sure there are a bunch that suffer silently and so teach us nothing :-).

Please feel free to reach out to blink-dev again if you notice blink changes that cause trouble for you (ideally, of course, while the change is in the Beta or Dev channels of chrome so that we have more options to mitigate the situation).

Rick 

Boris Zbarsky

unread,
Dec 11, 2014, 12:07:04 PM12/11/14
to Rick Byers, blink-dev
On 12/11/14, 11:37 AM, Rick Byers wrote:
> I think we're talking just about scrollTop/scrollLeft here.

That's fair, but when scrolling to named anchors whose positions depend
on the widths/heights of earlier content I think it's pretty easy to end
up with fractional scroll positions internally in Gecko without zoom
involved. Again, that may not be the case for Blink.

-Boris

Rick Byers

unread,
Dec 11, 2014, 2:39:45 PM12/11/14
to Boris Zbarsky, blink-dev, Yufeng Shen
Good point.  We're currently debating to what extent we should be trying to limit the exposure of fractional scroll offsets for the sake of web compat risk.  This is a good scenario for us to consider - perhaps we'd want to explicitly truncate/round in this case, or perhaps it's better to let floats flow naturally whenever possible.  I welcome additional input over on that input-dev thread.

Thanks!



-Boris

Levi Weintraub

unread,
Dec 11, 2014, 2:48:47 PM12/11/14
to Boris Zbarsky, PhistucK, blink-dev
On Thu, Dec 11, 2014 at 7: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.

This is the case in Blink as well. Fractional values are common in layout absent. I'd add to Boris' cases that lots of build-in css units like ems often result in fractions of pixels.

PhistucK

unread,
Dec 12, 2014, 5:39:30 AM12/12/14
to Boris Zbarsky, blink-dev
But why would that happen? offsetWidth and the rest are supposed to give you the actual value, am I right?
If so, on a 1 CSS pixel to 1 device pixel configuration, the actual value will not be fractional...


PhistucK

Mike Sherov

unread,
Dec 12, 2014, 7:39:38 AM12/12/14
to Michael Van Kleeck, blink-dev, Boris Zbarsky, PhistucK Productions
On Thu, Dec 11, 2014 at 11:48 AM, <mich...@gmail.com> wrote:
Very sensible, Rick. We rely on jQuery to insulate us as much as possible from ongoing changes in W3C specs and browsers like this, and this issue manifested for us through jQuery's scrollTop() API. I believe your approach is correct for Chromium, and that developers who rely on jQuery for insulation need to make sure we're engaged with jQuery to keep API's compatible as browser functionality improves. 

Unfortunately, scrollTop and scrollLeft are fairly straightforward through the normal DOM apis, so a lot of people skip using the jQuery methods. Also, speaking for jQuery, we *would* like jQuery.scrollTop and jQuery.scrollLeft to eventually support fractional values on an opt-in basis. Unfortunately, that doesn't look like it can happen here unless we use math and the results of gBCR.

Perhaps the true path forward is to continue making progress on gBCR speed improvements to the point where there's not much difference between that and the current APIS. 
 

To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.



--
Mike Sherov

Dave Methvin

unread,
Dec 12, 2014, 8:41:28 AM12/12/14
to blin...@chromium.org, bzba...@mit.edu


On Friday, December 12, 2014 5:39:30 AM UTC-5, PhistucK wrote:
But why would that happen? offsetWidth and the rest are supposed to give you the actual value, am I right?
If so, on a 1 CSS pixel to 1 device pixel configuration, the actual value will not be fractional...


The *correct* value can easily be fractional, offsetWidth is just rounding that value.

PhistucK

unread,
Dec 12, 2014, 10:30:44 AM12/12/14
to Dave Methvin, blink-dev, Boris Zbarsky
Hm, is offsetWidth rounding it, or is the rendering engine rounding it when it is displaying it?
(My screen width is 1366 pixels)
I took a screenshot and measured the result - the first box is 338 pixels wide, the second one is 337, the third one is 338 and the fourth one is 337.
offsetWidth reflects that as well.
(However, the Developer Tools feature shows 337.5 pixels as the width in the computed style pane for all of the boxes, but this is inaccurate as far as I measured).

What does need to happen when you have a 1 CSS pixel per 1 device pixel ratio and need to show fractional pixels? There are no half pixels. Do you expect some kind of a superimposition to happen (a pixel is shared between every two boxes that has a color calculated from the background colors of both of them)? That would be considered an bad artifact by many.


PhistucK

To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.

Boris Zbarsky

unread,
Dec 12, 2014, 11:11:07 AM12/12/14
to PhistucK, blink-dev
On 12/12/14, 5:38 AM, PhistucK wrote:
> But why would that happen? offsetWidth and the rest are supposed to give
> you the actual value, am I right?

Define "actual value"?

> If so, on a 1 CSS pixel to 1 device pixel configuration, the actual
> value will not be fractional...

If you have this markup:

<style>div { height: 40px; background: green; float: left }</style>
<div style="width: 90px; background: red">
<div style="width: 25%"></div>
<div style="width: 25%"></div>
<div style="width: 25%"></div>
<div style="width: 25%"></div>
</div>

Then even at 1 CSS pixel to 1 device pixel you will not see a red seam
anywhere in modern Firefox or Chrome.

I mean, yes, if you try this in old Chrome (e.g. 14) or Safari you will
see a 2px red seam on the right. But modern browsers will do subpixel
layout in this situation, with either antialiasing or inflation or both
on paint, depending on heuristics.

So are the "actual widths" fractional or not?

-Boris

PhistucK

unread,
Dec 12, 2014, 11:35:37 AM12/12/14
to Boris Zbarsky, blink-dev
The "actual value" is the actual value that is displayed to the user (the actual width of the box that is displayed).
337 and 338, in the example I gave in https://groups.google.com/a/chromium.org/d/msg/blink-dev/_Q7A4AQBFKY/BslMT_HKQp4J. This is not a fractional pixel... and a 1:1 CSS/device pixel screen cannot have a fractional pixel...


PhistucK

Levi Weintraub

unread,
Dec 12, 2014, 11:36:18 AM12/12/14
to PhistucK, Dave Methvin, blink-dev, Boris Zbarsky
Phistuck,

Blink does layout using these fractional values and snaps to pixels at paint time. A layout can come in at any time and change the number of physical pixels a box with a fractional size is rendered to, and so you may be keen on the actual size a box has for layout purposes.

For example, a box that's specified to be 100.5 pixels wide may be rendered to either 100 pixels or 101 pixels. If you only use offsetWidth to size another box that contains it, in a future layout you may either overflow or have a pixel of background shown.

PhistucK

unread,
Dec 12, 2014, 11:49:48 AM12/12/14
to Levi Weintraub, Dave Methvin, blink-dev, Boris Zbarsky
That is weird, unpredictable and unreliable, why would it be this way?


PhistucK

Boris Zbarsky

unread,
Dec 12, 2014, 12:23:22 PM12/12/14
to blink-dev
On 12/12/14, 11:49 AM, PhistucK wrote:
> That is weird, unpredictable and unreliable, why would it be this way?

Because snapping to the pixel grid (if it happens, instead of
antialiasing, which you ignored from my previous mail) happens at paint
time and depends on the relative position of the box and the pixel grid
at time of paint. So inserting some content above the box can change
how it gets snapped to the pixel grid, for example. As can scrolling.
And I assure you people don't expect scrolling to affect things like
offsetHeight.

In any case, if you compute sizes based on the pixel-grid-snapped
(again, if it happens) size then scrolling or relayout can change the
pixel grid snapping and your sizes will be off. On the other hand, if
you compute based on the engine's internal layout size then as long as
the snapping is consistent inside the engine there won't be a problem
for the common use cases where people like to compute sizes of things
(e.g. figuring out sizes of containers or sizes of overlays to position
on top of something).

-Boris

PhistucK

unread,
Dec 12, 2014, 12:45:09 PM12/12/14
to Boris Zbarsky, blink-dev
Anti aliasing means I will have a joined line that has colors from both of the boxes (assuming this colors are rgba(..., ..., ..., 0.5))? If so, I mentioned this in one of my replies as well - this seems to me like a bad artifact on the screen, that should never happen (it will be a color no one wanted or picked).

Your reply only increases my worries about this whole topic(?) and tells me that the web pretty much must move to sub pixel values.


PhistucK



-Boris

To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+unsubscribe@chromium.org.
Reply all
Reply to author
Forward
0 new messages