Re: [cssom] Element size/positioning information

On Apr 11, 2011, at 2:35 PM, Tab Atkins Jr. wrote:

> The current OM APIs for determining the size and position of an
> element are verbose and confusing.  There's been discussion on how to
> make this better, but it's been scattered and hasn't yet produced
> anything.  Chrome is interested in doing some experimental
> implementation in this space, but there's a lot of possible ways to do
> it, so I'd like to collect and restart the various discussions here.
> 
> 
> Determining the Size of an Element
> ==================================
> 
> Right now there are four ways of asking for the width of an element:
> elem.clientWidth, elem.scrollWidth,
> elem.getBoundingClientRect().width, and
> getComputedStyle(elem,'').width (similarly for height).

You forgot offsetWidth.

> All in all, these are the boxes that we might want to get sizing
> information about:
> 
> 1. content box, ignoring scrollbars
> 2. content box, subtracting scrollbars
> 3. content box, scrollable area
> 4. padding box (+/- scrollbars?  Depends on exactly where the impl
> puts the scrollbars.)
> 5. border box
> 6. transform-aware bounding box of at least the border box, possibly other boxes

WIth transformed elements, you may want a quad (set of four points corresponding to the corners),
or just the bounds of the transformed element.

Potentially split inlines also pose problems. You may want all the rects/quads, or just a bounding box/quad.

> 
> Position Relative to Another Element
> ====================================
> 
> Right now you can determine the position of an element relative to
> another element by figuring out their position relative to the same
> thing manually with one of the above methods, then subtracting one's
> top/left from the other.  Does this need to be made more convenient,
> so you can directly ask for something's position relative to something
> else?

I'd say no, since this gets hard with transforms. Authors can always
go via the viewport.

> Mouse Positioning
> =================
> 
> On a closely related tangent, the mouse events expose .clientX and
> .clientY properties which are relative to the viewport.  If you're
> trying to find the position of the mouse relative to an element (for
> example, if you're drawing something to a <canvas> where the mouse
> is), you have to find the position of the element relative to the
> viewport and subtract the two positions.  I think this is a good
> candidate for being made easier, so you can just request the mouse
> coords relative to an element.  Again, all of the boxes of an element
> are potential targets for being measured relative to.

And here again split inlines are troublesome.


> Mouse Positioning and Transfoms
> ===============================
> 
> When an element is being transformed, the position of the mouse
> relative to it is subtler.  You may want the actual position of the
> mouse relative to the current post-transform layout position of the
> element - this is easy to do by just subtracting the mouse position
> from the bounding-box position.  If you're drawing into a transformed
> <canvas>, though, you may want the position back in pre-transform
> coordinates, as if you took the stated mouse position and applied the
> element's inverse transform, so you can easily draw into the canvas
> and still have the visual display track the mouse.

I think you almost always want the event coordinates in the local coordinate
system of the element, which I think is what you're saying.

> Proposal
> ========
> 
> I'm not sure!  There's a lot of different possible approaches here.
> I'd like to optimize for author comprehensibility, which often means
> optimizing for terseness as well, but I'm not certain how best to do
> that.
> 
> For the simple measurement case, something like
> elem.cssBorderRect.width/height/top/right/bottom/left would work.  We
> could similarly expose cssPaddingRect, cssContentRect, cssScrollRect,
> etc.  Bounding boxes for transform-awareness can be requested as
> cssBoundingBorderRect - in the absence of transforms, these return the
> same information as their non-bounding equivalents.

I think you want to access these coordinate via the view (I know that MVC was
long flushed down the toilet with CSS/DOM, but I don't think we should give
up entirely).

So that would make it window.getCSSBorderRect(elem).left etc.

What happens on display:none elements?

> 
> Doing relative measurement is harder.  I'm not sure how I can tersely
> expose that information.  It may be acceptable to just say "hey,
> subtract the positions", given that getting the positions relative to
> the same thing would be easier.  If anyone has better ideas, feel free
> to pipe up.

I think you just compute both relative to a known base coordinate system
(client/document) and compare.

> The mouse positioning case has already received some attention - the
> last proposal I saw was for a MouseEvent.getCoordsAt(elem) function,
> which returns an object with .x and .y.  This is the point in the
> transformed space (the one you can easily use to draw something under
> the mouse with <canvas>).  This isn't *quite* sufficient, since it
> would presumably give you coordinates relative to the border box of
> the element, when you may want one of the other boxes, but it's close.
> 
> Finding the mouse position relative to an element in normal space can
> probably be done by just subtracting the positions, same as finding
> the relative positions of two elements.

I think the trickiest part here is elements with multiple boxes (split inlines,
paginated stuff etc).

Simon

Received on Monday, 11 April 2011 22:47:41 UTC