From: Garrett Smith on
On 2010-07-10 11:51 PM, David Mark wrote:
> On Jul 10, 11:31 pm, David Mark<dmark.cins...(a)gmail.com> wrote:
>> On Jul 7, 8:54 am, Richard Cornford<Rich...(a)litotes.demon.co.uk>
>> wrote:
>>
>>
>>
>>
>>
>>> On Jul 6, 10:38 pm, Garrett Smith wrote:
>>> <snip>> <http://blog.davglass.com/2009/01/browser-sniffing-vs-object-detection/>
>>
>>>> ... . The latter, Dav Glass' blog, is a classic example of bad
>>>> feature tests and used as a straw man for justifying browser
>>>> detection.
>>
>>> <snip>
>>
>>> That is exactly how it reads to me. This section, for example:-
>>
>>> | In my opinion, isn�t this the same thing as browser sniffing?
>>> | Aren�t you checking something that you know is unique about a
>>> | particular browser and leveraging it? Doesn�t that also qualify
>>> | as browser sniffing? If you are looking for some flaw in a
>>> | browser to determine a course of action, wouldn�t it be easier
>>> | to just read the User Agent and work from there? You can
>>> | process that info one time and use it everywhere.
>>
>> Yes, that is thoroughly laughable (like the example by Zakas). As is
>> his comment about IE being "off by 2".
>

[...]

> The punch-line is that the million-dollar question has a two-cent
> answer. From My Library:-
>
> if (ce.clientTop) { y -= ce.clientTop; }
> if (ce.clientLeft) { x -= ce.clientLeft; }
>
> Why subtract the border?

Can't really say without knowing whose border is being subtracted. Is
`ce` the "containing element" or the root element or something entirely
different?

(The identifier "ce" isn't clear)

Presumably because the coordinates will be
> used to position an element. And as the dated MS documentation
> indicates, this answer has been valid since 1999 (and unlikely to ever
> be invalid).
>
> If you can manage to avoid quirks mode and don't mind some degradation
> in IE5, then add this:-
>
> var ce = document.documentElement;
>
> But if writing a GP script, add one more line:-
>
> if (!ce.clientWidth) { ce = document.body; }
>
> Not very complicated.

That will fail when there is css width applied to the documentElement
and it will fail in browsers where the documentElement has a clientWidth
but is not acting as root.

You can check to see if compatMode exists and if it does, use it. Its
missing from versions of webkit, including Safari 3 an below and
probably a good number of mobile devices such as NOkias, so to provide a
check to see what the root element is, you can use that.

Why not use a separate method for getRootElement or IS_BODY_ACTING_ROOT?

Coincidentally, IE9pr3 seems to have a placeholder: document.rootElement
(null).

When the HTML element is not rendered (as in
> quirks mode and IE5), it has no client portion and therefore no client
> width. Even though this is based on (over a decade of) observation of
> MSHTML-based agents, as with most good inferences, it makes logical
> sense. And it's sort of documemted by MS as well. But like the
> getBoundingClientRect 2-pixel "quandary" this one is often addressed
> with voodoo based on faulty anecdotes found on dubious blogs (or sites
> like StackOverflow). I recently saw advice that only IE6 uses the
> BODY, so sniffing for that version might help. This was dated last
> week. :(
>
> Here is the documentation for clientTop:-
>
> http://msdn.microsoft.com/en-us/library/ms533565(VS.85).aspx
>
> "The difference between the offsetTop and the clientTop properties is
> the border area of the object."
>

That is not the correct formula. If it is ever true, it is only so by
coincidence.

> Like hell it is, MS! :( The difference between the offsetTop and
> clientTop properties is the offsetTop minus the top border (for what
> that's worth).
>

That is true in many implementations of offsetTop but is not
consistently true through versions of IE. Every official version of IE
has a different implementation of offsetTop. I haven't looked into IE9's
that much but it may end up different than IE8's.

Some implementations, notably IE8 (and IE9pr3) and various versions of
Opera, calculate offsetTop/offsetLeft from the layout parent's border
edge to the top-left point of the border of the child.

Other implementations calculate offsetTop from the layoutParent's
padding edge.

Calculating from the padding edge is how offset coords worked in older
versions. Sort of. There are other complications.

A draft of CSSOM-Views and concurrent (at that time) versions of Opera
specified that had that CSSOM-Views draft eventually changed, but IE
went on with what was in the draft, and I see it is still in IE9.

<http://www.w3.org/TR/2008/WD-cssom-view-20080222/#elementview-offsettop>

The draft changed to reflect reality, then reality changed to reflect
the old draft:
<http://www.w3.org/TR/cssom-view/#offset-attributes>

I anticipate that Microsoft, in effort to comply with the latest version
of the moving target draft, will change the implementation of IE9 so
that it calculates from the layout parent's padding edge, not its border
edge.
--
Garrett
From: Garrett Smith on
On 2010-07-11 12:36 PM, David Mark wrote:
> On Jul 6, 5:38 pm, Garrett Smith<dhtmlkitc...(a)gmail.com> wrote:
>> On 2010-07-06 02:00 PM, khinester wrote:
>>
>>> On Jul 6, 10:19 pm, Stefan Weiss<krewech...(a)gmail.com> wrote:
>>>> On 06/07/10 21:23, khinester wrote:
>>
[...]

> var temp = document.createElement("div");
> temp.style.cssText = "position:absolute;top:0;left:0";
> document.body.appendChild(temp);
> arguments.callee.offset = -temp.getBoundingClientRect().top;
> document.body.removeChild(temp);
> temp = null;
>
> Hmm. Create a DIV, set its style, append, measure, remove and
> "destroy" (quotes indicate setting to null is unneeded). I do wish I
> had never put that last step in,

Setting to null is totally pointless there.

but I didn't realize this pattern
> would eventually end up in every script on the planet. Too bad most
> of them use it wrong (as is the case here). See also jQuery.
>

Yeah, it got popular, though appendChild is wrong (operation aborted),
insertBefore(node, body.firstChild) is right to avoid operation aborted.

I see knowledge from this NG and code I have written as being
influential. I don't mind that at all.

Now if there was a way to get W3C spec authors to read this NG.
--
Garrett
From: David Mark on
On Jul 11, 5:00 pm, Garrett Smith <dhtmlkitc...(a)gmail.com> wrote:
> On 2010-07-10 11:51 PM, David Mark wrote:
>
>
>
>
>
> > On Jul 10, 11:31 pm, David Mark<dmark.cins...(a)gmail.com>  wrote:
> >> On Jul 7, 8:54 am, Richard Cornford<Rich...(a)litotes.demon.co.uk>
> >> wrote:
>
> >>> On Jul 6, 10:38 pm, Garrett Smith wrote:
> >>> <snip>>  <http://blog.davglass.com/2009/01/browser-sniffing-vs-object-detection/>
>
> >>>> ... . The latter, Dav Glass' blog, is a classic example of bad
> >>>> feature tests and used as a straw man for justifying browser
> >>>> detection.
>
> >>> <snip>
>
> >>> That is exactly how it reads to me. This section, for example:-
>
> >>> | In my opinion, isn’t this the same thing as browser sniffing?
> >>> | Aren’t you checking something that you know is unique about a
> >>> | particular browser and leveraging it? Doesn’t that also qualify
> >>> | as browser sniffing? If you are looking for some flaw in a
> >>> | browser to determine a course of action, wouldn’t it be easier
> >>> | to just read the User Agent and work from there? You can
> >>> | process that info one time and use it everywhere.
>
> >> Yes, that is thoroughly laughable (like the example by Zakas).  As is
> >> his comment about IE being "off by 2".
>
> [...]
>
> > The punch-line is that the million-dollar question has a two-cent
> > answer.  From My Library:-
>
> > if (ce.clientTop) { y -= ce.clientTop; }
> > if (ce.clientLeft) { x -= ce.clientLeft; }
>
> > Why subtract the border?
>
> Can't really say without knowing whose border is being subtracted.

It was a question I posed and answered at the same time.

> Is
> `ce` the "containing element" or the root element or something entirely
> different?
>
> (The identifier "ce" isn't clear)

I explained that too.

>
> Presumably because the coordinates will be
>
> > used to position an element.  And as the dated MS documentation
> > indicates, this answer has been valid since 1999 (and unlikely to ever
> > be invalid).
>
> > If you can manage to avoid quirks mode and don't mind some degradation
> > in IE5, then add this:-
>
> > var ce = document.documentElement;
>
> > But if writing a GP script, add one more line:-
>
> > if (!ce.clientWidth) { ce = document.body; }
>
> > Not very complicated.
>
> That will fail when there is css width applied to the documentElement
> and it will fail in browsers where the documentElement has a clientWidth
> but is not acting as root.

Wrong and wrong. Remember we are talking about using this with
getBoundingClientRect.

>
> You can check to see if compatMode exists and if it does, use it.

I thought so. See previous sentence.

> Its
> missing from versions of webkit, including Safari 3 an below and
> probably a good number of mobile devices such as NOkias, so to provide a
> check to see what the root element is, you can use that.

But that would be incorrect in this case.

>
> Why not use a separate method for getRootElement or IS_BODY_ACTING_ROOT?

I do (sort of) when it is appropriate. But "root" has no technical
meaning.

>
> Coincidentally, IE9pr3 seems to have a placeholder: document.rootElement
> (null).

Great.

>
> When the HTML element is not rendered (as in
>
>
>
> > quirks mode and IE5), it has no client portion and therefore no client
> > width.  Even though this is based on (over a decade of) observation of
> > MSHTML-based agents, as with most good inferences, it makes logical
> > sense.  And it's sort of documemted by MS as well.  But like the
> > getBoundingClientRect 2-pixel "quandary" this one is often addressed
> > with voodoo based on faulty anecdotes found on dubious blogs (or sites
> > like StackOverflow).  I recently saw advice that only IE6 uses the
> > BODY, so sniffing for that version might help.  This was dated last
> > week.  :(
>
> > Here is the documentation for clientTop:-
>
> >http://msdn.microsoft.com/en-us/library/ms533565(VS.85).aspx
>
> > "The difference between the offsetTop and the clientTop properties is
> > the border area of the object."
>
> That is not the correct formula.

As I said.

> If it is ever true, it is only so by
> coincidence.
>
> > Like hell it is, MS!  :(  The difference between the offsetTop and
> > clientTop properties is the offsetTop minus the top border (for what
> > that's worth).
>
> That is true in many implementations of offsetTop but is not
> consistently true through versions of IE.

Of course it is. It's basic math!

> Every official version of IE
> has a different implementation of offsetTop.

There you go again.

> I haven't looked into IE9's
> that much but it may end up different than IE8's.

All I know is that my fairly torturous Build Test page still works (in
HTML and XHTML renderings). At least it did in the last "preview" I
glanced at.

>
> Some implementations, notably IE8 (and IE9pr3) and various versions of
> Opera, calculate offsetTop/offsetLeft from the layout parent's border
> edge to the top-left point of the border of the child.

Old versions of Opera and if IE8 does that, I am blissfully unaware of
it as I my basic equations work regardless of such quirks.

>
> Other implementations calculate offsetTop from the layoutParent's
> padding edge.
>
> Calculating from the padding edge is how offset coords worked in older
> versions. Sort of. There are other complications.

All of this to dispute that A - B = A - B? Needless to say, it was a
waste of time.

>
> A draft of CSSOM-Views and concurrent (at that time) versions of Opera
> specified that had that CSSOM-Views draft eventually changed, but IE
> went on with what was in the draft, and I see it is still in IE9.

Doesn't matter to me a bit. My positioning code works in any event
(as we've seen).

>
> <http://www.w3.org/TR/2008/WD-cssom-view-20080222/#elementview-offsettop>
>
> The draft changed to reflect reality, then reality changed to reflect
> the old draft:
> <http://www.w3.org/TR/cssom-view/#offset-attributes>

Just ignore them. They don't matter a bit. Basic math is impervious
to the quasi-standards imposed on browsers.

>
> I anticipate that Microsoft, in effort to comply with the latest version
> of the moving target draft, will change the implementation of IE9 so
> that it calculates from the layout parent's padding edge, not its border
> edge.

I'm fine either way. ;)
From: David Mark on
On Jul 11, 5:00 pm, Garrett Smith <dhtmlkitc...(a)gmail.com> wrote:
> On 2010-07-10 11:51 PM, David Mark wrote:
>
>
>
>
>
> > On Jul 10, 11:31 pm, David Mark<dmark.cins...(a)gmail.com>  wrote:
> >> On Jul 7, 8:54 am, Richard Cornford<Rich...(a)litotes.demon.co.uk>
> >> wrote:
>
> >>> On Jul 6, 10:38 pm, Garrett Smith wrote:
> >>> <snip>>  <http://blog.davglass.com/2009/01/browser-sniffing-vs-object-detection/>
>
> >>>> ... . The latter, Dav Glass' blog, is a classic example of bad
> >>>> feature tests and used as a straw man for justifying browser
> >>>> detection.
>
> >>> <snip>
>
> >>> That is exactly how it reads to me. This section, for example:-
>
> >>> | In my opinion, isn’t this the same thing as browser sniffing?
> >>> | Aren’t you checking something that you know is unique about a
> >>> | particular browser and leveraging it? Doesn’t that also qualify
> >>> | as browser sniffing? If you are looking for some flaw in a
> >>> | browser to determine a course of action, wouldn’t it be easier
> >>> | to just read the User Agent and work from there? You can
> >>> | process that info one time and use it everywhere.
>
> >> Yes, that is thoroughly laughable (like the example by Zakas).  As is
> >> his comment about IE being "off by 2".
>
> [...]
>
> > The punch-line is that the million-dollar question has a two-cent
> > answer.  From My Library:-
>
> > if (ce.clientTop) { y -= ce.clientTop; }
> > if (ce.clientLeft) { x -= ce.clientLeft; }
>
> > Why subtract the border?
>
> Can't really say without knowing whose border is being subtracted. Is
> `ce` the "containing element" or the root element or something entirely
> different?
>
> (The identifier "ce" isn't clear)
>
> Presumably because the coordinates will be
>
> > used to position an element.  And as the dated MS documentation
> > indicates, this answer has been valid since 1999 (and unlikely to ever
> > be invalid).
>
> > If you can manage to avoid quirks mode and don't mind some degradation
> > in IE5, then add this:-
>
> > var ce = document.documentElement;
>
> > But if writing a GP script, add one more line:-
>
> > if (!ce.clientWidth) { ce = document.body; }
>
> > Not very complicated.
>
> That will fail when there is css width applied to the documentElement
> and it will fail in browsers where the documentElement has a clientWidth
> but is not acting as root.
>
> You can check to see if compatMode exists and if it does, use it. Its
> missing from versions of webkit, including Safari 3 an below and
> probably a good number of mobile devices such as NOkias, so to provide a
> check to see what the root element is, you can use that.
>

Boy you really made a mess of a clean explanation. Hard to tell what
you are claiming to be missing. I'll assume you mean
documentElement.clientWidth. If there really is an agent that
supports getBoundingClientRect, but not the clientWidth property for
the HTML element, then use this:-

ce.clientWidth === 0

That's what My Library uses, but I don't think it is strictly
necessary. For example, Safari 3 and below do not support
getBoundingClientRect. Furthermore, Safari 3 *does* feature
documentElement.clientWidth.

As to using compatMode, you are simply confusing the issue with other
tasks where a "root" or "acting root" may come into play due to the
mistakes that browser developers made when they copied the client*
properties from MS. For instance, measuring the viewport:-

http://www.cinsoft.net/viewport.html

You would NOT use the clientLeft/Top of the body in anything but IE
quirks mode (and IE 5). You don't want the borders of the body unless
the body is the viewport (and it never is in other browsers released
this century).

These are not wild theories. I've been using this code (or similar)
for over a decade. Well, at least until I realized I didn't really
need the absolute position of an element for anything. Regardless, My
Library still has such a function and it has been tested in every
major browser version (both DOM's and both rendering modes) published
this century. There are plenty of examples on the Build Test page.
From: David Mark on
On Jul 12, 7:04 pm, David Mark <dmark.cins...(a)gmail.com> wrote:
> On Jul 11, 5:00 pm, Garrett Smith <dhtmlkitc...(a)gmail.com> wrote:
>
>
>
>
>
> > On 2010-07-10 11:51 PM, David Mark wrote:
>
> > > On Jul 10, 11:31 pm, David Mark<dmark.cins...(a)gmail.com>  wrote:
> > >> On Jul 7, 8:54 am, Richard Cornford<Rich...(a)litotes.demon.co.uk>
> > >> wrote:
>
> > >>> On Jul 6, 10:38 pm, Garrett Smith wrote:
> > >>> <snip>>  <http://blog.davglass.com/2009/01/browser-sniffing-vs-object-detection/>
>
> > >>>> ... . The latter, Dav Glass' blog, is a classic example of bad
> > >>>> feature tests and used as a straw man for justifying browser
> > >>>> detection.
>
> > >>> <snip>
>
> > >>> That is exactly how it reads to me. This section, for example:-
>
> > >>> | In my opinion, isn’t this the same thing as browser sniffing?
> > >>> | Aren’t you checking something that you know is unique about a
> > >>> | particular browser and leveraging it? Doesn’t that also qualify
> > >>> | as browser sniffing? If you are looking for some flaw in a
> > >>> | browser to determine a course of action, wouldn’t it be easier
> > >>> | to just read the User Agent and work from there? You can
> > >>> | process that info one time and use it everywhere.
>
> > >> Yes, that is thoroughly laughable (like the example by Zakas).  As is
> > >> his comment about IE being "off by 2".
>
> > [...]
>
> > > The punch-line is that the million-dollar question has a two-cent
> > > answer.  From My Library:-
>
> > > if (ce.clientTop) { y -= ce.clientTop; }
> > > if (ce.clientLeft) { x -= ce.clientLeft; }
>
> > > Why subtract the border?
>
> > Can't really say without knowing whose border is being subtracted.
>
> It was a question I posed and answered at the same time.
>
> > Is
> > `ce` the "containing element" or the root element or something entirely
> > different?
>
> > (The identifier "ce" isn't clear)
>
> I explained that too.
>
>
>
>
>
> > Presumably because the coordinates will be
>
> > > used to position an element.  And as the dated MS documentation
> > > indicates, this answer has been valid since 1999 (and unlikely to ever
> > > be invalid).
>
> > > If you can manage to avoid quirks mode and don't mind some degradation
> > > in IE5, then add this:-
>
> > > var ce = document.documentElement;
>
> > > But if writing a GP script, add one more line:-
>
> > > if (!ce.clientWidth) { ce = document.body; }
>
> > > Not very complicated.
>
> > That will fail when there is css width applied to the documentElement
> > and it will fail in browsers where the documentElement has a clientWidth
> > but is not acting as root.
>
> Wrong and wrong.  Remember we are talking about using this with
> getBoundingClientRect.
>
>
>
> > You can check to see if compatMode exists and if it does, use it.
>
> I thought so.  See previous sentence.
>
> > Its
> > missing from versions of webkit, including Safari 3 an below and
> > probably a good number of mobile devices such as NOkias, so to provide a
> > check to see what the root element is, you can use that.
>
> But that would be incorrect in this case.
>
>
>
> > Why not use a separate method for getRootElement or IS_BODY_ACTING_ROOT?
>
> I do (sort of) when it is appropriate.  But "root" has no technical
> meaning.
>
>
>
> > Coincidentally, IE9pr3 seems to have a placeholder: document.rootElement
> > (null).
>
> Great.
>
>
>
>
>
>
>
> > When the HTML element is not rendered (as in
>
> > > quirks mode and IE5), it has no client portion and therefore no client
> > > width.  Even though this is based on (over a decade of) observation of
> > > MSHTML-based agents, as with most good inferences, it makes logical
> > > sense.  And it's sort of documemted by MS as well.  But like the
> > > getBoundingClientRect 2-pixel "quandary" this one is often addressed
> > > with voodoo based on faulty anecdotes found on dubious blogs (or sites
> > > like StackOverflow).  I recently saw advice that only IE6 uses the
> > > BODY, so sniffing for that version might help.  This was dated last
> > > week.  :(
>
> > > Here is the documentation for clientTop:-
>
> > >http://msdn.microsoft.com/en-us/library/ms533565(VS.85).aspx
>
> > > "The difference between the offsetTop and the clientTop properties is
> > > the border area of the object."
>
> > That is not the correct formula.
>
> As I said.
>
> > If it is ever true, it is only so by
> > coincidence.
>
> > > Like hell it is, MS!  :(  The difference between the offsetTop and
> > > clientTop properties is the offsetTop minus the top border (for what
> > > that's worth).
>
> > That is true in many implementations of offsetTop but is not
> > consistently true through versions of IE.
>
> Of course it is.  It's basic math!
>
> > Every official version of IE
> > has a different implementation of offsetTop.
>
> There you go again.
>
> > I haven't looked into IE9's
> > that much but it may end up different than IE8's.
>
> All I know is that my fairly torturous Build Test page still works (in
> HTML and XHTML renderings).  At least it did in the last "preview" I
> glanced at.
>
>
>
> > Some implementations, notably IE8 (and IE9pr3) and various versions of
> > Opera, calculate offsetTop/offsetLeft from the layout parent's border
> > edge to the top-left point of the border of the child.
>
> Old versions of Opera and if IE8 does that, I am blissfully unaware of
> it as I my basic equations work regardless of such quirks.
>
>
>
> > Other implementations calculate offsetTop from the layoutParent's
> > padding edge.
>
> > Calculating from the padding edge is how offset coords worked in older
> > versions. Sort of. There are other complications.
>
> All of this to dispute that A - B = A - B?  Needless to say, it was a
> waste of time.
>
>
>
> > A draft of CSSOM-Views and concurrent (at that time) versions of Opera
> > specified that had that CSSOM-Views draft eventually changed, but IE
> > went on with what was in the draft, and I see it is still in IE9.
>
> Doesn't matter to me a bit.  My positioning code works in any event
> (as we've seen).
>

And to head off the predictable. Thus far there has been *one* bug
found (in IE6) related to relatively positioned list items. It's
purely a bug in the browser and easy enough to test for (or avoid
altogether).

All of the ravings about differences in offset* implementations, spec
(or draft) recitals, etc. turned out to be a complete waste of time
(several months IIRC). As I stated from the start of those
"discussions", basic math is impervious to sloppy browser developers
and W3C drafts. Usually these problems have very simple solutions
that require only a modest amount of *thinking*.

Unfortunately, it seems most Web developers (and those who blog about
the subject) don't want to use their brains, preferring instead to
rant about their right to sniff the UA string (despite the obviously
poor results).

This latest offense (not brand new, but it's the first I've seen of
it) comes from the YUI camp. It's one browser sniffing devotee
whining about a bad example from another who is trying to reform but
not quite there yet. It's interesting that the latter developer wrote
that he "hates" his (incorrect) solution. Sounds just like a child's
cry of "I hate math!" :)

Dojo is teeming with UA sniffs, as was jQuery until they caught up to
the year 2003 and started with the object inferences (just another
form of browser sniffing). Same for Prototype, MooTools, Cappuccino,
GoogClosure, etc., etc. That's another reason why the average Web
developer gives up on even basic cross-browser problems. It's good
enough for Google and they can always change it later. Of course,
changing it later indicates a failure and sticking with failed
strategies year after year indicates madness.