<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://www.w3.org/Bugs/Public/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4"
          urlbase="https://www.w3.org/Bugs/Public/"
          
          maintainer="sysbot+bugzilla@w3.org"
>

    <bug>
          <bug_id>15430</bug_id>
          
          <creation_ts>2012-01-05 20:00:53 +0000</creation_ts>
          <short_desc>Interaction with getBoundingClientRect/elementFromPoint is not defined</short_desc>
          <delta_ts>2013-09-30 14:02:14 +0000</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>CSS</product>
          <component>CSSOM</component>
          <version>unspecified</version>
          <rep_platform>All</rep_platform>
          <op_sys>All</op_sys>
          <bug_status>RESOLVED</bug_status>
          <resolution>FIXED</resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords></keywords>
          <priority>P2</priority>
          <bug_severity>normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Aryeh Gregor">ayg</reporter>
          <assigned_to name="Simon Pieters">zcorpan</assigned_to>
          <cc>ayg</cc>
    
    <cc>cmarrin</cc>
    
    <cc>dino</cc>
    
    <cc>dschulze</cc>
    
    <cc>eoconnor</cc>
    
    <cc>glenn</cc>
    
    <cc>smfr</cc>
          
          <qa_contact>public-css-bugzilla</qa_contact>

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>62305</commentid>
    <comment_count>0</comment_count>
    <who name="Aryeh Gregor">ayg</who>
    <bug_when>2012-01-05 20:00:53 +0000</bug_when>
    <thetext>If a box is transformed, what values are reported for various CSSOM View features?  Specifically: getClientRects(), getBoundingClientRect(), clientTop, clientLeft, clientWidth, clientHeight, offsetTop, offsetLeft, offsetWidth, and offsetHeight.  CSSOM View assumes that everything is an axis-aligned rectangle, but transformed boxes will be parallelograms in general.

Using the Live DOM Viewer &lt;http://software.hixie.ch/utilities/js/live-dom-viewer/#&gt; with this test page:

----
&lt;!DOCTYPE html&gt;
&lt;style&gt;
body { margin: 0 }
div {
transform: rotate(45deg);
-ms-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-webkit-transform: rotate(45deg);
-o-transform: rotate(45deg);
height: 50px;
width: 50px;
background: blue;
}
&lt;/style&gt;
&lt;div&gt;&lt;/div&gt;
&lt;script&gt;
var div = document.querySelector(&quot;div&quot;);
w(div.getClientRects()[0].height);
w(div.getBoundingClientRect().height);
w(div.clientTop);
w(div.clientLeft);
w(div.clientWidth);
w(div.clientHeight);
w(div.offsetTop);
w(div.offsetLeft);
w(div.offsetWidth);
w(div.offsetHeight);
&lt;/script&gt;
----

I find that IE9, Firefox 12.0a1, Chrome 17 dev, and Opera Next 12.00 alpha all behave similarly: getClientRects() and getBoundingClientRect() reflects the transformed box (height is about 71 or 72 pixels), while client* and offset* reflect the untransformed box (0 and 50 pixels).  This should be standardized somewhere, probably in Transforms but perhaps in CSSOM View.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>62413</commentid>
    <comment_count>1</comment_count>
    <who name="Aryeh Gregor">ayg</who>
    <bug_when>2012-01-09 15:03:47 +0000</bug_when>
    <thetext>roc thinks this should be covered by CSSOM View, not Transforms:

http://lists.w3.org/Archives/Public/www-style/2012Jan/0325.html

There seems to be no Bugzilla component for CSSOM View, though, so I&apos;ll leave the bug here for now.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>63425</commentid>
    <comment_count>2</comment_count>
    <who name="Aryeh Gregor">ayg</who>
    <bug_when>2012-01-31 19:39:31 +0000</bug_when>
    <thetext>scrollIntoView() should also handle transforms:

https://bugzilla.mozilla.org/show_bug.cgi?id=703241</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>63432</commentid>
    <comment_count>3</comment_count>
    <who name="Aryeh Gregor">ayg</who>
    <bug_when>2012-01-31 20:05:52 +0000</bug_when>
    <thetext>Also needs thinking about: elementFromPoint, event.offsetX/offsetY, probably lots of other things . . .

https://bugs.webkit.org/show_bug.cgi?id=21870</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>64448</commentid>
    <comment_count>4</comment_count>
    <who name="Aryeh Gregor">ayg</who>
    <bug_when>2012-02-22 20:03:45 +0000</bug_when>
    <thetext>I propose that the specification say for now that:

* getBoundingClientRect() on both Element and Range must return the smallest rectangle that bound the transformed box.  If the transform is singular, the box will get mapped to a point or line segment, but this method must still return the smallest rectangle that contains that point or line segment.
* getClientRects() behaves the same.
* The HTMLElement properties clientTop, clientLeft, clientWidth, clientHeight, offsetTop, offsetLeft, offsetWidth, and offsetHeight all ignore transforms.  (This matches all browsers I tested in.  I&apos;m not totally sure whether it&apos;s a good idea for offset*, but we should spec it unless implementations want to change.)
* Hit-testing must respect transforms, as must elementFromPoint() and caretPositionFromPoint().
* The MouseEvent properties offsetX and offsetY must give the untransformed offset.  So if you have a 100px wide square that&apos;s scaled to only 50px, clicking at the right should give offsetX of 100, not 50.  This matches all browsers that implement offsetX/offsetY (Firefox doesn&apos;t).
* scrollIntoView() on a transformed element must scroll the transformed border box into view.  IE and WebKit get this right, Gecko and Opera get it wrong.  If the transform is singular, it still must scroll the topmost or bottommost point of the transformed box into view.

If there are no objections within at least two full workdays, I&apos;ll make the changes, as we agreed.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>64455</commentid>
    <comment_count>5</comment_count>
    <who name="Simon Fraser">smfr</who>
    <bug_when>2012-02-22 20:08:27 +0000</bug_when>
    <thetext>Sounds fine to me.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>64458</commentid>
    <comment_count>6</comment_count>
    <who name="Edward O&apos;Connor">eoconnor</who>
    <bug_when>2012-02-22 20:50:35 +0000</bug_when>
    <thetext>Sounds reasonable to me as well.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>64477</commentid>
    <comment_count>7</comment_count>
    <who name="Dirk Schulze">dschulze</who>
    <bug_when>2012-02-23 05:42:04 +0000</bug_when>
    <thetext>IMO this is something that should go to CSSOM View Module[1]. For the moment I am fine with defining it in CSS Transforms. But we should file a request to add the text into the current WD of CSSOM View Module. Or suggest the wording and ask the editors to add it.

If I understand it correctly, getBoundingClientRect() should cover the transformation as well? So should a CSSRect always be relative to the coordinate space of the top root element (means you get a rect which sides are parallel to the window border)?

+-----+
|    /\    |
|  /    \  |
|/        \|
|\        /|
|  \    /  |
|    \/    |
+-----+

So rhombus is a rotated div, the outer box is the bounding rect?

How about this example

&lt;div style=&quot;transform: rotate(22.5deg)&quot;&gt;
  &lt;div style=&quot;transform: rotate(22.5deg)&quot;&gt;
  &lt;/div&gt;
&lt;/div&gt;

How does the bounding rect look for the second (the nested) div box? Rotated by 22.5 degree, or in absolute coordinates?

Just to make sure. I want to know if the bounding rect is always in absolute coordinates, or in local coordinates but with the current transform applied.

What if you embed an iframe which gets transformed. The iframe contains other elements that are transformed as well. Is the bounding box in the coordinates of the iframe or in the coordinates of the top root element again?


Please note, that you can not change the behavior of getBoundingClientRect() and getClientRects() for SVG elements without an associated CSS layout box. Just to make sure what it means:

&lt;div&gt;
  &lt;svg&gt;
    &lt;rect /&gt;
    &lt;svg&gt;
      &lt;rect/&gt;
    &lt;/svg&gt;
  &lt;/svg&gt;
&lt;/div&gt;

The first SVG element (the direct child of the div box) is an SVG element with an associated CSS layout box. You can set margin, padding, border and so on. The other elements are not.

[1] http://www.w3.org/TR/cssom-view/</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>64478</commentid>
    <comment_count>8</comment_count>
    <who name="Glenn Adams">glenn</who>
    <bug_when>2012-02-23 05:48:18 +0000</bug_when>
    <thetext>(In reply to comment #7)
&gt; IMO this is something that should go to CSSOM View Module[1]. For the moment I
&gt; am fine with defining it in CSS Transforms. But we should file a request to add
&gt; the text into the current WD of CSSOM View Module. Or suggest the wording and
&gt; ask the editors to add it.
&gt; 
&gt; [1] http://www.w3.org/TR/cssom-view/

agreed; cssom-view is in process of being updated now, so i can fold this change in for the next ED</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>64488</commentid>
    <comment_count>9</comment_count>
    <who name="Simon Fraser">smfr</who>
    <bug_when>2012-02-23 15:39:07 +0000</bug_when>
    <thetext>(In reply to comment #7)
&gt; IMO this is something that should go to CSSOM View Module[1]. For the moment I
&gt; am fine with defining it in CSS Transforms. But we should file a request to add
&gt; the text into the current WD of CSSOM View Module. Or suggest the wording and
&gt; ask the editors to add it.

I would be fine with this too, and think that it&apos;s a better solution; it would be a little
odd for CSS Transforms to talk about CSS OM View interfaces, since no other CSS
spec does this AFAIK.

&gt; If I understand it correctly, getBoundingClientRect() should cover the
&gt; transformation as well? So should a CSSRect always be relative to the
&gt; coordinate space of the top root element (means you get a rect which sides are
&gt; parallel to the window border)?
&gt; 
&gt; +-----+
&gt; |    /\    |
&gt; |  /    \  |
&gt; |/        \|
&gt; |\        /|
&gt; |  \    /  |
&gt; |    \/    |
&gt; +-----+
&gt; 
&gt; So rhombus is a rotated div, the outer box is the bounding rect?

Yes.

&gt; How about this example
&gt; 
&gt; &lt;div style=&quot;transform: rotate(22.5deg)&quot;&gt;
&gt;   &lt;div style=&quot;transform: rotate(22.5deg)&quot;&gt;
&gt;   &lt;/div&gt;
&gt; &lt;/div&gt;
&gt; 
&gt; How does the bounding rect look for the second (the nested) div box? Rotated by
&gt; 22.5 degree, or in absolute coordinates?
&gt; 
&gt; Just to make sure. I want to know if the bounding rect is always in absolute
&gt; coordinates, or in local coordinates but with the current transform applied.

The client rect is obtained by mapping the 4 corners of the target element
into viewport coordinates, and then taking a bounding rect around those 4 points.
So the client rect is always viewport-aligned. This is true even for 3d-transformed elements.

&gt; What if you embed an iframe which gets transformed. The iframe contains other
&gt; elements that are transformed as well. Is the bounding box in the coordinates
&gt; of the iframe or in the coordinates of the top root element again?

Whatever getBoundingClientRect normally does, which I presume is return
a rect relative to the viewport of the window on which it is being called.

&gt; Please note, that you can not change the behavior of getBoundingClientRect()
&gt; and getClientRects() for SVG elements without an associated CSS layout box.
&gt; Just to make sure what it means:
&gt; 
&gt; &lt;div&gt;
&gt;   &lt;svg&gt;
&gt;     &lt;rect /&gt;
&gt;     &lt;svg&gt;
&gt;       &lt;rect/&gt;
&gt;     &lt;/svg&gt;
&gt;   &lt;/svg&gt;
&gt; &lt;/div&gt;
&gt; 
&gt; The first SVG element (the direct child of the div box) is an SVG element with
&gt; an associated CSS layout box. You can set margin, padding, border and so on.
&gt; The other elements are not.

I&apos;m not sure what you mean here.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>64501</commentid>
    <comment_count>10</comment_count>
    <who name="Aryeh Gregor">ayg</who>
    <bug_when>2012-02-23 19:12:58 +0000</bug_when>
    <thetext>(In reply to comment #7)
&gt; IMO this is something that should go to CSSOM View Module[1]. For the moment I
&gt; am fine with defining it in CSS Transforms. But we should file a request to add
&gt; the text into the current WD of CSSOM View Module. Or suggest the wording and
&gt; ask the editors to add it.

I think it belongs in CSSOM View ultimately, but it can live in Transforms for now if we can make the change there sooner.  If Glenn is willing to add it to CSSOM View soon, it doesn&apos;t need to go into Transforms.

&gt; If I understand it correctly, getBoundingClientRect() should cover the
&gt; transformation as well? So should a CSSRect always be relative to the
&gt; coordinate space of the top root element (means you get a rect which sides are
&gt; parallel to the window border)?

Right.

&gt; Just to make sure. I want to know if the bounding rect is always in absolute
&gt; coordinates, or in local coordinates but with the current transform applied.

Always relative to the viewport, in its coordinates.

&gt; What if you embed an iframe which gets transformed. The iframe contains other
&gt; elements that are transformed as well. Is the bounding box in the coordinates
&gt; of the iframe or in the coordinates of the top root element again?

The coordinates of whatever the window is for the element you call it on.  So the iframe&apos;s window, if it&apos;s in an iframe.  Methods on things in iframes don&apos;t know they&apos;re in an iframe.  This shouldn&apos;t have to do with transforms.

&gt; Please note, that you can not change the behavior of getBoundingClientRect()
&gt; and getClientRects() for SVG elements without an associated CSS layout box.
&gt; Just to make sure what it means:
&gt; 
&gt; &lt;div&gt;
&gt;   &lt;svg&gt;
&gt;     &lt;rect /&gt;
&gt;     &lt;svg&gt;
&gt;       &lt;rect/&gt;
&gt;     &lt;/svg&gt;
&gt;   &lt;/svg&gt;
&gt; &lt;/div&gt;
&gt; 
&gt; The first SVG element (the direct child of the div box) is an SVG element with
&gt; an associated CSS layout box. You can set margin, padding, border and so on.
&gt; The other elements are not.

Okay, so this should only be for things with a CSS layout box.  Fine by me.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>93560</commentid>
    <comment_count>11</comment_count>
    <who name="Simon Pieters">zcorpan</who>
    <bug_when>2013-09-19 13:39:01 +0000</bug_when>
    <thetext>(In reply to Aryeh Gregor from comment #4)
&gt; * getBoundingClientRect() on both Element and Range must return the smallest
&gt; rectangle that bound the transformed box.  If the transform is singular, the
&gt; box will get mapped to a point or line segment, but this method must still
&gt; return the smallest rectangle that contains that point or line segment.
&gt; * getClientRects() behaves the same.

I think the spec does this now. Please verify.

https://dvcs.w3.org/hg/csswg/rev/d6d6ed08b91a

&gt; * The HTMLElement properties clientTop, clientLeft, clientWidth,
&gt; clientHeight, offsetTop, offsetLeft, offsetWidth, and offsetHeight all
&gt; ignore transforms.  (This matches all browsers I tested in.  I&apos;m not totally
&gt; sure whether it&apos;s a good idea for offset*, but we should spec it unless
&gt; implementations want to change.)

Done.

https://dvcs.w3.org/hg/csswg/rev/6091febd3717

It seems that in Gecko, offsetParent can be an ancestor that has a transform set. Blink/WebKit/IE9 don&apos;t do that.

http://software.hixie.ch/utilities/js/live-dom-viewer/saved/2535</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>93565</commentid>
    <comment_count>12</comment_count>
    <who name="Simon Pieters">zcorpan</who>
    <bug_when>2013-09-19 14:04:22 +0000</bug_when>
    <thetext>(In reply to Aryeh Gregor from comment #4)
&gt; * Hit-testing must respect transforms, as must elementFromPoint() and
&gt; caretPositionFromPoint().

http://software.hixie.ch/utilities/js/live-dom-viewer/saved/2536

We don&apos;t have a spec for hit testing, but I fixed elementFromPoint, elementsFromPoint and caretPositionFromPoint.

https://dvcs.w3.org/hg/csswg/rev/0e33c7674d1e</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>93567</commentid>
    <comment_count>13</comment_count>
    <who name="Simon Pieters">zcorpan</who>
    <bug_when>2013-09-19 14:11:56 +0000</bug_when>
    <thetext>(In reply to Aryeh Gregor from comment #4)
&gt; * The MouseEvent properties offsetX and offsetY must give the untransformed
&gt; offset.  So if you have a 100px wide square that&apos;s scaled to only 50px,
&gt; clicking at the right should give offsetX of 100, not 50.  This matches all
&gt; browsers that implement offsetX/offsetY (Firefox doesn&apos;t).

http://software.hixie.ch/utilities/js/live-dom-viewer/saved/2537

Fixed.

https://dvcs.w3.org/hg/csswg/rev/2623f63c16ee</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>93569</commentid>
    <comment_count>14</comment_count>
    <who name="Simon Pieters">zcorpan</who>
    <bug_when>2013-09-19 14:25:47 +0000</bug_when>
    <thetext>(In reply to Aryeh Gregor from comment #4)
&gt; * scrollIntoView() on a transformed element must scroll the transformed
&gt; border box into view.  IE and WebKit get this right, Gecko and Opera get it
&gt; wrong.  If the transform is singular, it still must scroll the topmost or
&gt; bottommost point of the transformed box into view.

Can you elaborate on what you think is right here?

In http://software.hixie.ch/utilities/js/live-dom-viewer/saved/2538 Gecko seems to do what you want (the topmost point of the transformed box is scrolled into view), while Bilnk does the opposite (the pre-transform &quot;top&quot; border edge is scrolled into view).</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>93573</commentid>
    <comment_count>15</comment_count>
    <who name="Simon Fraser">smfr</who>
    <bug_when>2013-09-19 15:13:11 +0000</bug_when>
    <thetext>(In reply to Simon Pieters from comment #14)
&gt; (In reply to Aryeh Gregor from comment #4)
&gt; &gt; * scrollIntoView() on a transformed element must scroll the transformed
&gt; &gt; border box into view.  IE and WebKit get this right, Gecko and Opera get it
&gt; &gt; wrong.  If the transform is singular, it still must scroll the topmost or
&gt; &gt; bottommost point of the transformed box into view.
&gt; 
&gt; Can you elaborate on what you think is right here?
&gt; 
&gt; In http://software.hixie.ch/utilities/js/live-dom-viewer/saved/2538 Gecko
&gt; seems to do what you want (the topmost point of the transformed box is
&gt; scrolled into view), while Bilnk does the opposite (the pre-transform &quot;top&quot;
&gt; border edge is scrolled into view).

I think the correct behavior is to take the transforms into account for scrollIntoView() (seems like Blink is wrong).</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>93593</commentid>
    <comment_count>16</comment_count>
    <who name="Simon Pieters">zcorpan</who>
    <bug_when>2013-09-20 11:43:23 +0000</bug_when>
    <thetext>OK. The spec already does that now with the change to getBoundingClientRect(), AFAICT.

Please reopen or file new bugs if there are cases not covered by the spec.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>94013</commentid>
    <comment_count>17</comment_count>
    <who name="Aryeh Gregor">ayg</who>
    <bug_when>2013-09-30 14:02:14 +0000</bug_when>
    <thetext>At a glance, LGTM -- thanks!</thetext>
  </long_desc>
      
      

    </bug>

</bugzilla>