Intent to Deprecate: SVGElement.offsetParent/offsetTop/offsetLeft/offsetWidth/offsetHeight

937 views
Skip to first unread message

Philip Jägenstedt

unread,
Nov 4, 2015, 4:44:20 PM11/4/15
to blink-dev

Primary eng (and PM) emails

phi...@opera.com


Summary

Deprecate the attributes offsetParent, offsetTop, offsetLeft, offsetWidth and offsetHeight on SVGElement.


Motivation

We have already removed these attributes from Element, see the intents to deprecate and remove.


Compatibility Risk

In Gecko and Edge, these attributes are only supported on HTMLElement. Nevertheless, there was some breakage when they were removed from Element (see deprecation thread) and it's reasonable to expect something to break now as well. If the breakage is bad we can go back and try to change the specs, of course.


Note that for the inner SVG elements like <rect> and <circle> these attributes return 0, because those aren't part of the CSS box model. They do work for the <svg> element itself, however.

Alternative implementation suggestion for web developers

Use getBoundingClientRect(). It's not a drop-in replacement, however, as it takes transforms into account.


Usage information from UseCounter

offsetParent: https://www.chromestatus.com/metrics/feature/timeline/popularity/887

offsetTop: https://www.chromestatus.com/metrics/feature/timeline/popularity/888

offsetLeft: https://www.chromestatus.com/metrics/feature/timeline/popularity/889

offsetWidth: https://www.chromestatus.com/metrics/feature/timeline/popularity/890

offsetHeight: https://www.chromestatus.com/metrics/feature/timeline/popularity/891


The highest of these are offsetWidth and offsetHeight, both in the 0.03-0.04% range.

OWP launch tracking bug

https://crbug.com/463116


Entry on the feature dashboard

https://www.chromestatus.com/features/5724912467574784


Requesting approval to remove too?

No, first deprecate for two release cycles (M48-49), with the deprecation message saying that it will be gone in M50. A separate intent to remove will be sent.

Rick Byers

unread,
Nov 4, 2015, 5:24:18 PM11/4/15
to Philip Jägenstedt, blink-dev
If these don't exist at all on current Edge builds, then I think the risk of real breakage is pretty small.  Edge is pretty relentless about adding such APIs when they improve compat with real sites.  Maybe much of the usage is gated via feature detection, or maybe this is another example of some library copying all the enumerable properties.

LGTM1 to deprecate.

Chris Harrelson

unread,
Nov 4, 2015, 8:50:11 PM11/4/15
to Rick Byers, Philip Jägenstedt, blink-dev
Looks fine to me.

FYI deprecation doesn't need 3 LGTMs.

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

Rick Byers

unread,
Nov 4, 2015, 10:05:34 PM11/4/15
to Chris Harrelson, Philip Jägenstedt, blink-dev
On Wed, Nov 4, 2015 at 8:49 PM, Chris Harrelson <chri...@chromium.org> wrote:
Looks fine to me.

FYI deprecation doesn't need 3 LGTMs.

Whoops sorry - thanks for the reminder.

Philip Jägenstedt

unread,
Nov 5, 2015, 4:01:48 AM11/5/15
to Rick Byers, Chris Harrelson, blink-dev
Thanks Rick and Chris, I'll make it so!

It had already been mentioned in the bug, but another commenter pointed out again that this incompatibility is the cause jQuery's custom :hidden and :visible selector work differently for SVG in Blink/WebKit and other engines. In short it's a jQuery bug, but see my comment and test for details.

Erik Dahlström

unread,
Nov 5, 2015, 5:30:10 AM11/5/15
to blink-dev, Philip Jägenstedt
What about the case of inline (outermost) <svg> elements that are laid out using the css box model? Deprecate those cases too?

Yes, it doesn't look like the offset* properties are supported on <svg> in Gecko, but OTOH why shouldn't it work for that case? Seems somewhat useful, and also would be inconsistent wrt other elements if it wasn't there.

Just my 2c.
/ed

Philip Jägenstedt

unread,
Nov 5, 2015, 7:32:49 AM11/5/15
to Erik Dahlström, blink-dev, Boris Zbarsky
Yes, the plan is to deprecate and then remove the attributes on SVGElement, leaving them only on HTMLElement, which would break the case of inline <svg> elements.

If these attributes were spec'd for SVGElement or perhaps Element and other implementors were interested in that, then that would be fine, but the bug was filed by Boris Zbarsky, so at least for him that wasn't the first choice.

Note that the definitions of these attributes have special cases for various HTML elements, so they couldn't be made entirely generic.

Boris Zbarsky

unread,
Nov 5, 2015, 10:20:54 AM11/5/15
to Philip Jägenstedt, Erik Dahlström, blink-dev
On 11/5/15 7:32 AM, Philip Jägenstedt wrote:
> If these attributes were spec'd for SVGElement or perhaps Element and
> other implementors were interested in that, then that would be fine, but
> the bug <https://code.google.com/p/chromium/issues/detail?id=463116> was
> filed by Boris Zbarsky, so at least for him that wasn't the first choice.

Because we should be discouraging the use of offset*, not encouraging
it. For one thing, the offset* APIs return incorrect values any time
element sizes/positions are not integer CSS pixels, which is happening
more and more now that browsers are doing subpixel font layout and
running on high-dpi screens. This is an unending source of author
confusion and bug reports that get marked as invalid by browsers
(because changing these APIs to return non-integer values breaks websites).

Given that, I consider these APIs unfortunate legacy we're stuck with
for compat reasons and have zero interest in adding them to things where
web compat doesn't already require them.

-Boris

Erik Dahlström

unread,
Nov 5, 2015, 10:41:25 AM11/5/15
to Philip Jägenstedt, Boris Zbarsky, blink-dev
To me this sounds like you want to deprecate HTMLElement.offset* too. Is
that not possible?

Do the Element.offset* UseCounters cover that case or not?
/ed

Philip Jägenstedt

unread,
Nov 5, 2015, 10:50:29 AM11/5/15
to Erik Dahlström, Boris Zbarsky, blink-dev
The use counters we had for these attributes on Element would only be hit by non-HTML, non-SVG elements, since the attributes were also added to those prototypes at the same time. This was deliberate, because it never struck me as a possibility that these APIs would be possible to remove from HTMLElement.

Philip

Boris Zbarsky

unread,
Nov 5, 2015, 10:59:58 AM11/5/15
to Erik Dahlström, Philip Jägenstedt, blink-dev
On 11/5/15 10:41 AM, Erik Dahlström wrote:
> To me this sounds like you want to deprecate HTMLElement.offset* too.

It'd be nice if we could, but I expect the usage is sky-high. If
someone wants to measure for sure, data is always nice, of course.

-Boris

Dave Methvin

unread,
Feb 4, 2016, 4:56:00 PM2/4/16
to blink-dev, e...@chromium.org, phi...@opera.com, bzba...@mit.edu
Please note the distant thunder in https://github.com/jquery/jquery/issues/2895 .

Although jQuery doesn't formally support SVG in most of what it does because it's an HTML DOM library, there is a good chance that people are using jQuery for SVG position information nonetheless. The the back-compat issues would cause issues with the last 10 years of jQuery versions. In addition, the ticket mentions we're in a bit of a tough spot because it's not clear what we can use to replace the deprecated offsetParent functionality.

Philip Jägenstedt

unread,
Feb 5, 2016, 3:31:26 AM2/5/16
to Dave Methvin, blink-dev, Erik Dahlström, Boris Zbarsky
Thanks for notifying us, Dave!

It's true that there's no replacement for offsetParent, sorry about
that incorrect guidance. That these attributes aren't supported in
Edge or Gecko means that we must be dealing with some
non-interoperable code, and that was part of the motivation for
deprecating this, and wanting to remove it.

I've commented on the GitHub issue to ask for the code in question. A
separate Intent to Remove will be sent before this is actually
removed, so it's great that we learned about this first.

Philip Jägenstedt

unread,
Feb 5, 2016, 3:33:31 AM2/5/16
to Dave Methvin, blink-dev, Erik Dahlström, Boris Zbarsky, Simon Pieters
As for a replacement, I don't suppose anybody ever suggested this for CSSOM? Simon? (context)

cosm...@gmail.com

unread,
Feb 10, 2016, 1:51:00 PM2/10/16
to blink-dev
I just started seeing this error on our site around February 8th 2016. I feel two months is cutting this shockingly close. This may break our entire site and our normal release cycles are about this long.

We inline SVG elements into the page and use jQuery offsetHeight() on these elements. Others might be doing the same. See https://github.com/iconic/SVGInjector

-Charlie

cosm...@gmail.com

unread,
Feb 10, 2016, 1:53:13 PM2/10/16
to blink-dev, cosm...@gmail.com
My mistake, I meant to say we use outerHeight() in jQuery.

-Charlie

Philip Jägenstedt

unread,
Feb 16, 2016, 2:28:54 PM2/16/16
to cosm...@gmail.com, blink-dev
Hi Charlie, and apologies for the slow reply.

Can you point to the problematic code in SVGInjector? I can't find "outerHeight" in a web search at least. Does it work in other browsers?

Philip

--
You received this message because you are subscribed to the Google Groups "blink-dev" group.

cosm...@gmail.com

unread,
Feb 16, 2016, 3:55:56 PM2/16/16
to blink-dev, cosm...@gmail.com
We use SVGInjector which just inlines the SVG element. After that, we had code that was using the jquery $element.height(). jQuery was using the deprecated calls, as previous posters indicated, because it did not special case SVG elements.

I have since changed our code to use $element[0].getBoundingClientRecet().height.

As for the deprecation of these APIs, I would suggest a patch be submitted to jQuery, wait for a release that includes the patch, then deprecate in Chrome giving a few months for people to update their jQuery library (or dependent systems like WordPress or the like that uses jQuery). Some users don't have the wherewithal to fix code that depends on this deprecated API in the two months the Chrome team is giving developers to fix this. If it's not a security problem, I don't know what the hurry is to deprecate this (albeit maybe broken) API.

-Charlie

Dave Methvin

unread,
Feb 16, 2016, 4:56:12 PM2/16/16
to blink-dev, cosm...@gmail.com

As for the deprecation of these APIs, I would suggest a patch be submitted to jQuery, wait for a release that includes the patch, then deprecate in Chrome giving a few months for people to update their jQuery library (or dependent systems like WordPress or the like that uses jQuery). Some users don't have the wherewithal to fix code that depends on this deprecated API in the two months the Chrome team is giving developers to fix this. If it's not a security problem, I don't know what the hurry is to deprecate this (albeit maybe broken) API.

The issue is that getBoundingClientRect returns fractional values that take transforms into account whereas properties like offsetHeight return integers. The jQuery team considered that to be a breaking change so we are only making it with the major-version jQuery 3.0 which should be out in the next few months. We did not make the change specifically to support SVG, although it might coincidentally do that. Regardless, even if we added this risky patch to a 1.x or 2.x maintenance release to increase its distribution there will be literally millions of sites using older versions of jQuery forever on the web because people just don't update old sites. The question the usage counters can't answer is whether slow-to-upgrade sites using older jQuery are also the ones using jQuery's dimensional APIs for SVG.

Since offsetHeight and friends are inaccurate in a subpixel-and-transforms world I agree it seems like a good idea to get rid of them--if it doesn't break too much stuff. For now I'd just leave in the deprecation warning and we'll keep an eye open for an Intent to Remove with the idea it could happen once jQuery 3.0 releases.

cosm...@gmail.com

unread,
Feb 16, 2016, 6:49:14 PM2/16/16
to blink-dev, cosm...@gmail.com
I'm also getting this warning when using $('*:visible'). I have worked around it by using this: 

$('*').filter(function(){return $(this).closest('svg').length == 0;}).filter(':visible:empty')

Understood about jQuery introducing a breaking change. As it is, if Google moves forward and removes this API, sites will break harder than they would if jQuery introduced the breaking change in question.

I suppose I'm making some assumptions here. What will happen when code calls this method after the api is removed per the depreciation warning?

-Charlie

Philip Jägenstedt

unread,
Feb 16, 2016, 9:39:09 PM2/16/16
to cosm...@gmail.com, blink-dev
jQuery's :hidden and :visible selectors were discussed in https://code.google.com/p/chromium/issues/detail?id=463116#c22 and following comments.

Because of how they use offsetWidth and offsetHeight, SVG elements will always be considered hidden and never visible. When it comes to doing the right thing, upgrading to jQuery 2.2.0 or later looks like the right move, since it fixed this:

However, that wouldn't suppress the deprecation message. You could perhaps try monkey-patching jQuery with something like this:
jQuery.expr.filters.visible = function( elem ) {
  return elem.getClientRects().length > 0;
};
If you have something that works in Firefox and Edge you should be good whether or not the deprecation message is triggered.

Dave Methvin

unread,
Feb 16, 2016, 11:04:56 PM2/16/16
to blink-dev, cosm...@gmail.com
On Tuesday, February 16, 2016 at 6:49:14 PM UTC-5, cosm...@gmail.com wrote:
I'm also getting this warning when using $('*:visible'). I have worked around it by using this: 

$('*').filter(function(){return $(this).closest('svg').length == 0;}).filter(':visible:empty')

I know it's off-topic for this list but I've got to warn that $("*:visible") is probably one of the most expensive selectors you can use. It will go through every element on the page and check its width/height to see if it's taking up space on the page. For a typical web page this can be 2,000 or more elements. If layout is dirty, for example if the HTML or CSS has been changed above that selector, using $("*:visible") will inevitably force layout for the whole page. I can't think of any reason an application would ever want to use "*" as a selector. There have to be better solutions for your case, but it's best to take that discussion elsewhere such as StackOverflow.

cosm...@gmail.com

unread,
Feb 22, 2016, 7:31:42 PM2/22/16
to blink-dev
In the future, when this sort of deprecation occurs, it would be very helpful for the in-browser warnings to include stack traces and for there to be an option to break when hit like there are for exceptions.

Also, I think deprecation notices like this one should also include a 'what will happen if you don't update your code' section. Will calls accessing the offsetHeight attribute cause a javascript error? Will they fail silently? Will they just return 0? Will their value be undefined?

-Charlie


On Wednesday, November 4, 2015 at 3:44:20 PM UTC-6, Philip Jägenstedt wrote:

Philip Jägenstedt

unread,
Feb 23, 2016, 1:03:29 AM2/23/16
to Charlie Hayes, blink-dev
Thanks Charlie, those are good suggestions.

I've filed "allow breaking on deprecation messages and show stack traces" but don't know if that's an easy fix or insanely complicated. Let's see.

As for what happens if you don't update, it's true of all IDL attribute removals that the attributes will simply not exist, so trying to access them will return undefined and `'offsetParent' in svgElement` will evaluate to false. How it will break depends on the surrounding code, though.

I have now posted an Intent to Remove for this.

--

Joe Medley

unread,
Feb 23, 2016, 11:02:04 AM2/23/16
to Philip Jägenstedt, Charlie Hayes, blink-dev
I think this is a really good idea. If you agree, go star the ticket to show your support.

Joe Medley | Technical Writer, Chrome DevRel | jme...@google.com | 816-678-7195
If an API's not documented it doesn't exist.

ling...@gmail.com

unread,
Sep 3, 2016, 3:56:58 AM9/3/16
to blink-dev, phi...@opera.com
Ok, but then how do you know get the position of the svg element in vanilla javascript?

PhistucK

unread,
Sep 3, 2016, 8:08:27 AM9/3/16
to ling...@gmail.com, blink-dev, Philip Jägenstedt
Does element.getBoundingClientRect() and friends suit your need (mentioned in the intent)?

(Nit - "vanilla JavaScript" is quite a big term here, this is a DOM API, not an ECMAScript API. It is just a method in "vanilla JavaScript")


PhistucK

On Sat, Sep 3, 2016 at 10:56 AM, <ling...@gmail.com> wrote:
Ok, but then how do you know get the position of the svg element in vanilla javascript?

--
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+unsubscribe@chromium.org.

ling...@gmail.com

unread,
Sep 3, 2016, 8:14:29 AM9/3/16
to blink-dev, ling...@gmail.com, phi...@opera.com
element.getBoundingClientRect() indeed suits my need so far, my bad.





PhistucK

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

Reply all
Reply to author
Forward
0 new messages