Re: [cssom] Element size/positioning information

On Mon, Apr 11, 2011 at 3:00 PM, Boris Zbarsky <bzbarsky@mit.edu> wrote:
> On 4/11/11 2:35 PM, Tab Atkins Jr. wrote:
>>
>> 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).
>
> Of course the clientWidth thing is only needed for web compat.

I did not know that clientWidth was solely for compat. >_<

> The other
> three return totally different things from each other; which one you want
> depends on what you're measuring.
>
>> (In case people are unaware of what the first two actually
>> do, I made a diagram some time ago at
>> <http://www.xanthir.com/diagrams/scrollwidth-clientwidth.html>.)
>
> That diagram is .... wrong unless you're using a different meaning of
> "content width" than the usual one.
>
> The clientWidth of an element is as you say.
>
> The scrollWidth, however, has to do with the amount of scrolling the element
> can do.  This is not actually related to the "width" of the content in any
> layout sense (e.g. relative positioning of children affects scrollWidth.

Right; I tried to indicate that at least somewhat in the diagram by
having overflowing text which affects the scrollWidth.  I don't know
how to indicate clearly that positioned elements would also mess with
this.


>> The first three return the size in pixels as an integer
>
> This is false, except in some UAs that choose to clamp widths to integers.
>  For example, in Gecko elem.getBoundingClientRect().width will return the
> width actually used for layout of the element as a double.

Right; consider that a slip of the tongue.  I meant "number".


>> while the fourth returns size in pixels as a string with 'px' at the end.
>
> This is also false.  The computed style width is "auto" for non-replaced
> inlines in Gecko, for example

Oh god, that's so horrible.  >_<  Everything about these APIs is messed up.

(I thought getComputedStyle() was supposed to return the used value of
'width'?  That should be an actual number for every element, right?
The only transformation left is the conversion from used->actual,
which is just pixel rounding.)


> (and that's ignoring elements that are not
> rendered, for which the computed style width can be any specified width
> value).

Yeah, but that's a separate and more-or-less irrelevant issue.  If
you're asking for the width of non-rendered elements you're doing
something wrong.


>> The third is transform-aware, while the others ignore any transforms on
>> the
>> element.
>
> This is true in Webkit, but not in Gecko.  In Gecko none of these take
> transforms into account.

Again, oh god, that's so horrible.  >_<


>> 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
>
> What does this mean, exactly?  Scrollbars go into the padding, generally...
>  They don't usually affect the size of the content box, right?

If you don't have enough padding, the scrollbar still pushes content around.


>> 3. content box, scrollable area
>
> Is this meant to be the thing scroll* currently returns?

Yes.


>> 5. border box
>> 6. transform-aware bounding box of at least the border box, possibly other
>> boxes
>
> We probably need the margin box as well.  Or whatever the right thing is to
> return for code that wants to size things on a line by subtracting the
> widths of some stuff from the block width and then setting the width of some
> box to what's left.

Sigh, yeah.  Margin box is hard/nonsensical in the presence of
collapsing, but otherwise is useful.


>> Right now, there are two ways to get the position of an element:
>> elem.offsetTop/Left (gives you coords relative to the element's
>> positioning root), and
>> elem.getBoundingClientRect().top/right/bottom/left (post-transform
>> coords of the bounding box relative to the viewport).
>
> Again, that's not actually what those do in all browsers.

I'm assuming the difference is again relative to whether transforms are honored?


>> 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?
>
> It's unclear what this even means in a world with transforms, by the way....

Agreed, which is another reason I'm not sure about handling this
specially.  I think we can probably get away with just exposing layout
boxes (pre-transform) and bounding boxes (post-transform) and letting
the author diff the positions themself.

>> 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 what it's worth, I think this may be the wrong working group for this.
>  The fact that getBoundingClientRect ended up in CSSOM in the first place is
> pretty weird to me...  The various working groups that have actual
> experience with DOM API design might be better venues for designing more DOM
> APIs.

The problem, of course, is ensuring that the people designing the API
have a sufficient understanding of CSS to make the right choices here.
 But I can bring this up in HTML or Webapps or something if we think
that's better.

~TJ

Received on Monday, 11 April 2011 22:48:38 UTC