- From: Simon Fraser <smfr@me.com>
- Date: Mon, 11 Apr 2011 15:46:50 -0700
- To: "Tab Atkins Jr." <jackalmage@gmail.com>
- Cc: www-style list <www-style@w3.org>
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