W3C home > Mailing lists > Public > www-style@w3.org > May 2011

Re: [CSSOM] Revisiting transforms and getBoundingClientRect()

From: Andrew Dupont <w3@andrewdupont.net>
Date: Wed, 18 May 2011 23:29:08 -0500
Cc: www-style@w3.org
Message-Id: <BE01E6A6-6ADB-4459-8A36-131A3F97555B@andrewdupont.net>
To: Tab Atkins Jr. <jackalmage@gmail.com>

> Let's discuss use-cases.  You say you've done experiments with
> transforms, Andrew.  Do some of these correspond to actual actions
> you've tried to perform in client's sites?  If so, what actions, and
> what information would have made it easier to do if it were exposed?

I'm answering this first because it's most important: knowing _exactly where the element is on the screen_, as the user views it, is the crucial thing. Without that, you can't do drag-and-drop on elements with transforms applied; you can't position one transformed element underneath another; you can't center a transformed element within the viewport (to name just a few examples).

Now, some might argue that I'll still be able to figure out where a transformed element is on the screen even without a new API, and they're arguably right. Firefox's getBoundingClientRect() isn't transform-aware, but I'm pretty sure I could do some math based on the transform values and get the "real" coordinates. But you could argue the same thing about getBoundingClientRect() itself, an API which JS libraries embraced because it gave consistent results and let us trim a lot of bloat from our code. [1]

The other major issue is whether there will be an API that reaches through both CSS transforms and CSS transitions/animations. Right now, WebKit's version of getBoundingClientRect() does this; I can (e.g.) animate `scale(2.0) translate(0, 0)` to `scale(2.0) translate(-500px, 0)`, call getBoundingClientRect() every 0.1s during the animation, and watch the value change in accordance with what I'm seeing on the screen.

On May 17, 2011, at 12:57 PM, Tab Atkins Jr. wrote:

> 1. Which box to measure - content, padding, border, or margin?

Border box, if we're being most consistent with existing APIs.

> 2. What concept of 'box' to use - partitions (generated boxes,
> possibly multiple due to lines/columns/etc), bounding box (always only
> one, may be surprisingly large), or positioning box (single box in
> local coordinates, ignoring partition splitting).

My vote is for bounding box. The other types of box may suit others' purposes, so I don't want to dismiss them altogether, but bounding box is what I care most about.

> 3. What are the coordinates relative to - window origin, or origin of
> another element (potentially letting you measure "within" a transform)

Honestly, I love the fact that getBoundingClientRect() returns viewport-relative coordinates; when all elements measure their coordinates from the same arbitrary origin, it's tremendously simple to measure any two elements relative to one another. So any consistent origin — viewport origin, document origin, or whatever — would be my vote.

> 4. Whether to care about transforms, and how much - ignore the
> transform (values are in box-local space, may not interact well with
> some types of #3 relative coords), respect the transform (returning
> quads rather than rectangles), or give a bounding box for the
> transform (respecting transform, but returning a circumscribing rect).

For simplicity's sake, my vote would be for the circumscribing bounding box. To have an API that understands that elements may not share the same axes as the page itself… well, it'd be the first such API for HTML, as far as I know, and I'm not asking for that kind of complexity unless someone is willing to take it on.

Let's say I've got a square element that's been given a `transform` of `rotate(45deg)`. By inspecting that `transform` style and getting the coordinates of its circumscribing rect, I can rely on math for the rest; I can figure out the element's actual dimensions and, therefore, the coordinates of its four vertices. And from there I'd be able to do anything else I wanted — determine how much it overlapped another element, etc.

Bonus points if some API (either the same one or a different one) can give me transform-aware _dimensions_ of the element in question, thus saving me step one of the process I described above.

> I'm not sure which of these axises* are useful for authors, and which
> we should expose directly (some can be easily computed from other
> types of data).

The only hesitation I have with having to compute measurements/coordinates is that sometimes there are subtle differences between what the math tells me and what the browser ends up doing. Any loss of fidelity — e.g, if the ClientRect returned by the browser gives me integers instead of floats — can produce measurements that are ~1px off (or more).

Not saying we need to expose everything directly, just that what we do expose should be precise enough to take the guesswork out of the math.


[1] http://ejohn.org/blog/getboundingclientrect-is-awesome/
Received on Thursday, 19 May 2011 04:29:38 UTC

This archive was generated by hypermail 2.3.1 : Monday, 2 May 2016 14:38:46 UTC