FAQ Topic - How do I find the size of the window? (2009-12-23)

F

FAQ server

-----------------------------------------------------------------------
FAQ Topic - How do I find the size of the window?
-----------------------------------------------------------------------

Here is a detailed explanation of a cross-browser strategy to
find the dimensions of the viewport, excepting all chrome
(excludes scrollbars, etc).

We can consider various properties:

window.innerWidth
document.clientWidth
document.documentElement.clientWidth
document.body.clientWidth

Of the browsers that have an ` innerWidth ` property, most
include scrollbar dimensions. Some versions of KHTML browsers
(including Safari 2) do _not_ include scrollbar width.

The ` window.inner* ` properties are unreliable and not
useful here. We don't want scrollbar dimensions included.

document.clientWidth

Certain versions of KHTML, including Safari 2, have
` document.clientHeight ` and ` document.clientWidth `
properties. Where supported, these rare properties accurately
return the height and width of the viewport, without including
scrollbar dimensions.

document.documentElement.clientWidth
document.body.clientWidth

MSHTML (Trident), Firefox (Gecko), Opera (Presto), and Safari
(Webkit) all support ` clientHeight ` on ` document.body `
and ` document.documentElement `. The difficulty is figuring out
which one is reliable. In other words which object to get the
` clientHeight ` property from:` documentElement ` or ` body `?

What the number returned from either of these properties
represents depends on the environment. The environment includes
the browser, its version, and the rendering mode of the document.
In quirks mode, we'll mostly want to use ` body.clientHeight `
(except for in Safari 2).

document.body.clientHeight

Some environments will return the viewport height. Others will
return ` 0 `. Yet others will return the ` clientHeight ` of
the ` BODY ` element.

document.documentElement.clientHeight

This is the more "standard" property for getting the height of
the viewport. It usually "works" in modern browsers in
standards mode. Notable exceptions include Safari 2 and
Opera <= 9.25, both of which return the ` clientHeight `
of the ` html ` _element_. (Oddly, Opera <= 9.25
in standards mode returns the width of the viewport for
` documentElement.clientWidth `).

With the exception of Safari 2, ` body.clientHeight ` is reliable
where ` documentElement.clientHeight ` is found to be unreliable.
For example, in Safari 3+, Opera, and Mozilla, all in quirks mode,
` document.documentElement.clientHeight ` returns the ` clientHeight `
of the ` html ` element (this may seem unsurprising but
it is not what we want).

Conversely, ` document.body.clientHeight ` will return
the height of the viewport in most cases where
` document.documentElement.clientHeight ` does not. An exception
to that is Safari 2, where ` documentElement.clientHeight `
and ` body.clientHeight ` both return the height of their
corresponding element (not what we want).

By using a combination of Feature Testing and Capability Testing,
the dimensions of the viewport can be strategically retrieved
from the property that works in the environment the script is
running in. The trick is determining which property will give us
the value we want.

Since ` document.clientHeight ` is reliable where
(rarely) supported, and since browsers that support this property
don't return the viewport dimensions from
` document.body.clientHeight ` or
` document.documentElement.clientHeight `, this should be the
very first condition:

// Safari 2 uses document.clientWidth (default).
if(typeof document.clientWidth == "number") {
// use document.clientWidth.
}

The next strategy is to determine if
` document.documentElement.clientHeight ` property is unreliable.
It is deemed "unreliable" when it is either ` 0 ` or taller
than the viewport.

Determining if ` documentElement.clientHeight ` is ` 0 ` is easy.
The result is stored in a variable ` IS_BODY_ACTING_ROOT `.

var docEl = document.documentElement,
IS_BODY_ACTING_ROOT = docEl && docEl.clientHeight === 0;
docEl = null;

To determine if ` documentElement.clientHeight ` returns
a value taller than the viewport, we need a Capability Test.

If we can force ` documentElement ` to be very tall
(taller than a normal viewport) we can then check to see if
` documentElement.clientHeight ` returns that "very tall" number.
If it does, then it is unreliable.

We can force ` documentElement ` to be taller than the viewport
(or any "normal" viewport) by adding a ` div ` to the ` body `,
give that ` div ` a height larger than any normal monitor,
and then check to see if ` documentElement.clientHeight ` is
that high (or "almost" that high, to account for ` documentElement `
having a border).

// Used to feature test Opera returning wrong values
// for documentElement.clientHeight.
// The results of this function should be cached,
// so it does not need to be called more than once.
function isDocumentElementHeightOff(){
var d = document,
div = d.createElement('div');
div.style.height = "2500px";
d.body.insertBefore(div, d.body.firstChild);
var r = d.documentElement.clientHeight > 2400;
d.body.removeChild(div);
return r;
}

We can use this function to see if we should use
` body.clientHeight `, instead. (but only after checking if
` document.clientHeight ` is supported).

// Safari 2 uses document.clientWidth (default).
if(typeof document.clientWidth == "number") {
// use document.clientHeight/Width.
}
else if(IS_BODY_ACTING_ROOT || isDocumentElementHeightOff()) {
// use document.body.clientHeight/Width.
} else {
// use document.documentElement.clientHeight/Width.
}

The preceding strategy was developed by Garrett Smith with input
from John David Dalton. A complete and tested example can be found
in APE Library under ` APE.dom.getViewportDimensions `.
Source code:

http://dhtmlkitchen.com/ape/build/dom/viewport-f.js

APE is publicly released under Academic Free License.
APE home:

http://dhtmlkitchen.com/ape/


Note: The dimensions cannot be determined accurately until after
the document has finished loading.

http://msdn.microsoft.com/en-us/library/ms533566(VS.85).aspx

http://developer.mozilla.org/en/DOM/window.innerWidth

http://dev.opera.com/articles/view/using-capability-detection/


The complete comp.lang.javascript FAQ is at
http://jibbering.com/faq/
 
G

Garrett Smith

FAQ said:
-----------------------------------------------------------------------
FAQ Topic - How do I find the size of the window?
-----------------------------------------------------------------------
[...]


document.body.clientHeight

Some environments will return the viewport height. Others will
return ` 0 `. Yet others will return the ` clientHeight ` of
the ` BODY ` element.

document.documentElement.clientHeight

This is the more "standard" property for getting the height of
the viewport.

In quirks mode, document.documentElement.clientHeight will return
element height (not the height of the viewport is returned).

For an example go to: http://example.com/ and try:
javascript: alert(document.documentElement.clientHeight)

"80" is the result in many browsers.

How much value is added by supporting quirks mode?

To address this, there was a proposal to test document.compatMode.

There are a couple of problems I have with document.compatMode:
1) nonstandard and may be absent
2) does not tell specific details about a particular thing, but just
about the rendering mode in general.
3) version ignorant. There is only "BackCompat" and "CSS1Compat".

Scripts should not depend on non-standard features to function. Wherever
possible try to use a standard.

It may an option, however, to use backcompat to identify not Quirks Mode:

if(document.compatMode !== "BackCompat") {

}

This will fail for quirks mode documents where there is no compatMode.
[...]
 
D

David Mark

FAQ said:
-----------------------------------------------------------------------
FAQ Topic - How do I find the size of the window?
-----------------------------------------------------------------------
[...]


document.body.clientHeight

Some environments will return the viewport height. Others will
return ` 0 `. Yet others will return the ` clientHeight ` of
the ` BODY ` element.
document.documentElement.clientHeight

This is the more "standard" property for getting the height of
the viewport.

In quirks mode, document.documentElement.clientHeight will return
element height (not the height of the viewport is returned).

For an example go to:http://example.com/and try:
javascript: alert(document.documentElement.clientHeight)

"80" is the result in many browsers.

How much value is added by supporting quirks mode?

To address this, there was a proposal to test document.compatMode.

There are a couple of problems I have with document.compatMode:
1) nonstandard and may be absent
2) does not tell specific details about a particular thing, but just
about the rendering mode in general.
3) version ignorant. There is only "BackCompat" and "CSS1Compat".

Scripts should not depend on non-standard features to function. Wherever
possible try to use a standard.

It may an option, however, to use backcompat to identify not Quirks Mode:

if(document.compatMode !== "BackCompat") {

}

This will fail for quirks mode documents where there is no compatMode.
[...]

http://www.cinsoft.net/viewport.asp
 
D

David Mark

David said:
FAQ server wrote:
-----------------------------------------------------------------------
FAQ Topic - How do I find the size of the window?
-----------------------------------------------------------------------
[...]
document.body.clientHeight
Some environments will return the viewport height. Others will
return ` 0 `. Yet others will return the ` clientHeight ` of
the ` BODY ` element.
document.documentElement.clientHeight
This is the more "standard" property for getting the height of
the viewport.
In quirks mode, document.documentElement.clientHeight will return
element height (not the height of the viewport is returned).
For an example go to:http://example.com/andtry:
javascript: alert(document.documentElement.clientHeight)
"80" is the result in many browsers.
How much value is added by supporting quirks mode?
To address this, there was a proposal to test document.compatMode.
There are a couple of problems I have with document.compatMode:
1) nonstandard and may be absent
2) does not tell specific details about a particular thing, but just
about the rendering mode in general.
3) version ignorant. There is only "BackCompat" and "CSS1Compat".
Scripts should not depend on non-standard features to function. Wherever
possible try to use a standard.
It may an option, however, to use backcompat to identify not Quirks Mode:
if(document.compatMode !== "BackCompat") {
}
This will fail for quirks mode documents where there is no compatMode.
[...]

Took quick look at that.

| Some older KHTML-based browsers (e.g. Safari 2) feature
| document.clientHeight/Width properties. These properties are arguably
| a better alternative to measuring elements, but are apparently no
| longer in production.

document.clientWidth measures the viewport, not elements.

That's exactly what I said. I use them instead of measuring elements
(when they are featured).
I've reformatted the code to use spaces, not tabs. The code should use
spaces instead of tabs. This is even more important when publishing
code publicly, and especially when posting code publicly for code review.

I know that.
The scrollChecks function is not very clear. It returns either an object
or undefined. It seems to be a feature test function, but I don't
understand the strategies it is using.

It's just creating an object to house various properties. Yes, it is
a feature test.
| scrollChecks = (function()
|   var oldBorder, body = doc.body,
| result = { compatMode: doc.compatMode };
|   var clientHeight = html.clientHeight,
| bodyClientHeight = body.clientHeight;
|   var elDiv = doc.createElement('div');
|   elDiv.style.height = '100px';
|   body.appendChild(elDiv);
|
|   // (GS) What is the reason for `clientHeight != html.clientHeight`?
|   result.body = !clientHeight || clientHeight != html.clientHeight;
|   // (GS) What is the reason for this?
|   result.html = bodyClientHeight != body.clientHeight;

What does appending a 100px div to body have to do with
html.clientHeight? Or body.clientHeight?

What you are calling the simple wrapper seems complicated. You have:

| if (typeof window.innerHeight == 'number') {
|
|   // This fork is for most modern non-IE browsers
|   // In this simplified example, this is a sniff for non-IE browsers
|   // The longer version uses window.innerHeight for some cases,
|   // adjusting for scroll bars when possible.
|
|   getViewportDimensions = function(win) {

Checking innerHeight to try to detect "not IE".

That's the simplified example version. The reason it has that odd
structure is that the (slightly) longer version (as I noted in the
comments) actually _uses_ window.innerHeight/Width in that fork.
There are a few problems with this inference.

The code in that branch does not use innerHeight at all.

See above.
The inference is not forwards compatible. It assumes that MSIE won't
ever implement innerHeight.

See above.
The inference can prevent IE from implementing innerHeight. If used
wideley enough, this code can prevent IE from implementing the
innerHeight property because if they do, pages using this code will break..

See above. And look at the original version (though neither version
suffers from what you describe at all).
CSSOM Views WD specifies window.innerHeight. MSIE 8 implemented some of
that draft. This draft was mentioned as early as 2007, when ^^^^^

discussing
Find Element Position. I also mentioned it in the thread about
getComputedStyle Where is My LI (or something like that), and also
recently when you questioned quoodoox comment about the standard for
innerHeight.

http://www.w3.org/TR/cssom-view/

You are going on about nothing. That's not a standard either.
Anyway, it is a really poor inference there.

So, you basically latched on to my comment about that very inference,
which makes perfect sense in the unabridged version and has no bad
implications in the abridged at all. There's no problem with future
IE versions entering that top fork (the part you cropped) if and when
they decide to support innerWidth/Height. Furthermore, you glossed
over the part that really matters (the feature testing).
I'm going to stop there for now.

You might as well as you aren't getting anywhere.
 
D

David Mark

[...]
|
|   // (GS) What is the reason for `clientHeight != html.clientHeight`?

You hid these comments.
|   result.body = !clientHeight || clientHeight != html.clientHeight;
|   // (GS) What is the reason for this?
|   result.html = bodyClientHeight != body.clientHeight;

What does appending a 100px div to body have to do with
html.clientHeight? Or body.clientHeight?

Think about it. What happens for the one with the scrollbar. What
happens for the one without. ;)
What you are calling the simple wrapper seems complicated.

I missed this too. BS. It's as simple as it's going to get if you
want it to work. :)
 
G

Garrett Smith

David said:
[...]
Took quick look at that.

| Some older KHTML-based browsers (e.g. Safari 2) feature
| document.clientHeight/Width properties. These properties are arguably
| a better alternative to measuring elements, but are apparently no
| longer in production.

document.clientWidth measures the viewport, not elements.

That's exactly what I said. I use them instead of measuring elements
(when they are featured).

Ah, it seems the wording is not so good.

It could seem like a better alternative to measure elements would be
document.clientHeight. When the goal is not measuring elements, but
measuring the viewport.
It's just creating an object to house various properties. Yes, it is
a feature test.

Didn't want to answer?
That's the simplified example version. The reason it has that odd
structure is that the (slightly) longer version (as I noted in the
comments) actually _uses_ window.innerHeight/Width in that fork.

That is the last example on the page. Was there something that you
forgot to include in your document?

[...]
You are going on about nothing. That's not a standard either.

It is good indication of a forthcoming standard. IE8 already changed
from IE7 to match some of that, reverting to closer to the way it was in
IE6 for offsetParent being BODY.
 
D

David Mark

[...]
|
|   // (GS) What is the reason for `clientHeight != html.clientHeight`?

You hid these comments.
|   result.body = !clientHeight || clientHeight != html.clientHeight;
|   // (GS) What is the reason for this?
|   result.html = bodyClientHeight != body.clientHeight;
What does appending a 100px div to body have to do with
html.clientHeight? Or body.clientHeight?

Think about it.  What happens for the one with the scrollbar.  What
happens for the one without.  ;)


What you are calling the simple wrapper seems complicated.

I missed this too.  BS.  It's as simple as it's going to get if you
want it to work.  :)

Also, looking at the abridged version, it could be simplified further
by using just the first fork. IE (past, present or future) will be
fine with that. In the longer version, there are calculations done
with innerWidth/Height in the first fork, which is how there came to
be two. The inference was never for IE, but for agents with no
innerWidth/Height properties to fall back on.

The scrollChecks feature testing is simple enough and likely makes the
extra innerWidth/Height (and scrollbar width) calculations unnecessary
(that part predates scrollChecks). I may well end up removing those
calculations, which would result in a single fork for all.
 
D

David Mark

David said:
David Mark wrote:
FAQ server wrote:
[...]
[...]
http://www.cinsoft.net/viewport.asp
Took quick look at that.
| Some older KHTML-based browsers (e.g. Safari 2) feature
| document.clientHeight/Width properties. These properties are arguably
| a better alternative to measuring elements, but are apparently no
| longer in production.
document.clientWidth measures the viewport, not elements.
That's exactly what I said.  I use them instead of measuring elements
(when they are featured).

Ah, it seems the wording is not so good.

I guess.
It could seem like a better alternative to measure elements would be
document.clientHeight. When the goal is not measuring elements, but
measuring the viewport.

I don't care for that wording either.
Didn't want to answer?

See the post a minute later. You hid those questions.
That is the last example on the page. Was there something that you
forgot to include in your document?

No. Read to the end.

"See the source for a slightly more robust rendition."
[...]
You are going on about nothing.  That's not a standard either.

It is good indication of a forthcoming standard.

Doesn't matter in this case. Let IE adopt innerWidth/Height all they
want. See my other response.
IE8 already changed
from IE7 to match some of that, reverting to closer to the way it was in
IE6 for offsetParent being BODY.

Doesn't really matter. But offsetParent being BODY for what?
 
G

Garrett Smith

David said:
David said:
David Mark wrote:
FAQ server wrote:
-----------------------------------------------------------------------
FAQ Topic - How do I find the size of the window?
-----------------------------------------------------------------------
[...] [...]

[...]
http://www.cinsoft.net/viewport.asp
Took quick look at that.
| Some older KHTML-based browsers (e.g. Safari 2) feature
| document.clientHeight/Width properties. These properties are arguably
| a better alternative to measuring elements, but are apparently no
| longer in production.
document.clientWidth measures the viewport, not elements.
That's exactly what I said. I use them instead of measuring elements
(when they are featured).
Ah, it seems the wording is not so good.

I guess.
It could seem like a better alternative to measure elements would be
document.clientHeight. When the goal is not measuring elements, but
measuring the viewport.

I don't care for that wording either.

It was not a suggestion. What you wrote is ambiguous; it leaves open for
possible interpretation that the author's goal is measuring elements.
See the post a minute later. You hid those questions.

No, that is not true.

What do scrollChecks.body and scrollChecks.html mean?
No. Read to the end.

"See the source for a slightly more robust rendition."

That code has a very a poor inference. Your code comment indicates that
you are trying to filter "not ie". that may likely be error prone in the
future.

Accusing me of hiding something that was in plain view is immature. I
posted it right in the message with my initials. I do post such
line-by-line code comments in reviews here on this NG, on my site, and
other places.

http://groups.google.com/group/comp.lang.javascript/msg/6bc787294a819e69
http://groups.google.com/group/comp.lang.javascript/msg/ce4f73671872cf28?dmode=source
[...]
http://www.w3.org/TR/cssom-view/
You are going on about nothing. That's not a standard either.
It is good indication of a forthcoming standard.

Doesn't matter in this case. Let IE adopt innerWidth/Height all they
want. See my other response.

In your existing code, IE <=8 gets the `else` branch. If IE9 implements
CSSOM Views innerHeight, then IE will get the first branch and will use
the scrollChecks object, possibly BODY for calculations when HTML should
be used instead.
Doesn't really matter. But offsetParent being BODY for what?

I have explained this to you before but I will explain it once again.

Take an element E whose offsetParent was documentElement in IE7. In IE8,
the E's offsetParent is BODY, or, if E is BODY, E's offsetParent is now
null. This is similar in behavior to IE6. Gerard Talbot filed this as a
bug on connect.microsoft.com and it was "fixed" by the IE Team.

I dislike having to remember such trivia and opposed that change in a
bug comment. But that is beside the point.

Not only is it possible that IE9 will implement this feature, it is
likely. CSSOM Views has seen continued updates by the editor, recent
updates, and is a Working Draft status.
 
D

David Mark

David said:
David Mark wrote:
David Mark wrote:
FAQ server wrote:
-----------------------------------------------------------------------
FAQ Topic - How do I find the size of the window?
-----------------------------------------------------------------------
[...]
[...]
[...]
http://www.cinsoft.net/viewport.asp
Took quick look at that.
| Some older KHTML-based browsers (e.g. Safari 2) feature
| document.clientHeight/Width properties. These properties are arguably
| a better alternative to measuring elements, but are apparently no
| longer in production.
document.clientWidth measures the viewport, not elements.
That's exactly what I said.  I use them instead of measuring elements
(when they are featured).
Ah, it seems the wording is not so good.
I don't care for that wording either.

It was not a suggestion. What you wrote is ambiguous; it leaves open for
possible interpretation that the author's goal is measuring elements.
Okay.
See the post a minute later.  You hid those questions.

No, that is not true.

It doesn't matter what your intent was. The end result is that they
were buried in my cited code (where I wouldn't expect to find your
inline comments buried without white space to set them apart).
What do scrollChecks.body and scrollChecks.html mean?

They are interim feature testing results which get scratched
(scrollChecks is undefined) if they are equal. They are used
internally and indicate that the body or html is the element holding
the appropriate client* properties. Ultimately, the result could be a
single flag as only mutually exclusive results are retained.
That code has a very a poor inference. Your code comment indicates that
you are trying to filter "not ie". that may likely be error prone in the
future.

It certainly does NOT. Stop reading my comments about which browsers
have been observed to follow which forks and read the _logic_.
There's no "not IE" to it. In fact, as noted, IE is fine with either
of those two forks.
Accusing me of hiding something that was in plain view is immature.

Somehow, I knew you'd go on and on about that. The fact is, that you
buried them without white space. Who cares? Get over _that_.
I
posted it right in the message with my initials.

And? That's supposed to be SOP? No white space at all, but initials?
I do post such
line-by-line code comments in reviews here on this NG, on my site, and
other places.

And likely nobody ever sees them and you assume you were right. I can
definitely see that. :)
http://groups.google.com/group/comp.../group/comp.lang.javascript/msg/ce4f73671872c...
[...]
http://www.w3.org/TR/cssom-view/
You are going on about nothing.  That's not a standard either.
It is good indication of a forthcoming standard.
Doesn't matter in this case.  Let IE adopt innerWidth/Height all they
want.  See my other response.

In your existing code, IE <=8 gets the `else` branch. If IE9 implements
CSSOM Views innerHeight, then IE will get the first branch and will use
the scrollChecks object, possibly BODY for calculations when HTML should
be used instead.

You are dead wrong. Read the code again and realize IE will work with
either fork, whether it implements innerWidth/Height or not. And, as
mentioned, that extra innerWidth/Height stuff is likely unneeded at
this point. The verson in the FAQ completely _ignores_ those
properties anyway. So what are you trying to say?
I have explained this to you before but I will explain it once again.

You don't have to explain anything to me, except your assertion about
"offsetParent being BODY" for... what? You just want to talk about
something else (CSSOM I imagine).
Take an element E whose offsetParent was documentElement in IE7. In IE8,
the E's offsetParent is BODY, or, if E is BODY, E's offsetParent is now
null. This is similar in behavior to IE6. Gerard Talbot filed this as a
bug on connect.microsoft.com and it was "fixed" by the IE Team.

I dislike having to remember such trivia and opposed that change in a
bug comment. But that is beside the point.

And _someone_ else. :)
Not only is it possible that IE9 will implement this feature, it is
likely. CSSOM Views has seen continued updates by the editor, recent
updates, and is a Working Draft status.

I know. It's worthless at this point, particularly for this
discussion. Why you go on and on about it is beyond me? Are you
speaking to some other audience?
 
G

Garrett Smith

David said:
David said:
David Mark wrote:
David Mark wrote:
FAQ server wrote:
-----------------------------------------------------------------------
FAQ Topic - How do I find the size of the window?
-----------------------------------------------------------------------
[...]
[...]
[...]
http://www.cinsoft.net/viewport.asp
Took quick look at that.
| Some older KHTML-based browsers (e.g. Safari 2) feature
| document.clientHeight/Width properties. These properties are arguably
| a better alternative to measuring elements, but are apparently no
| longer in production.
document.clientWidth measures the viewport, not elements.
That's exactly what I said. I use them instead of measuring elements
(when they are featured).
Ah, it seems the wording is not so good.
I guess.
It could seem like a better alternative to measure elements would be
document.clientHeight. When the goal is not measuring elements, but
measuring the viewport.
I don't care for that wording either.
It was not a suggestion. What you wrote is ambiguous; it leaves open for
possible interpretation that the author's goal is measuring elements.
Okay.
The scrollChecks function is not very clear. It returns either an object
or undefined. It seems to be a feature test function, but I don't
understand the strategies it is using.
It's just creating an object to house various properties. Yes, it is
a feature test.
| scrollChecks = (function()
| var oldBorder, body = doc.body,
| result = { compatMode: doc.compatMode };
| var clientHeight = html.clientHeight,
| bodyClientHeight = body.clientHeight;
| var elDiv = doc.createElement('div');
| elDiv.style.height = '100px';
| body.appendChild(elDiv);
|
| // (GS) What is the reason for `clientHeight != html.clientHeight`?
| result.body = !clientHeight || clientHeight != html.clientHeight;
| // (GS) What is the reason for this?
| result.html = bodyClientHeight != body.clientHeight;
What does appending a 100px div to body have to do with
html.clientHeight? Or body.clientHeight?
Didn't want to answer?
See the post a minute later. You hid those questions.
No, that is not true.

It doesn't matter what your intent was. The end result is that they
were buried in my cited code (where I wouldn't expect to find your
inline comments buried without white space to set them apart).

I often leave initial in comment for line-by-line. Example:

| // (GS) What is this line for?

I could add a preceeding line break. What else would make line-by-line
comment more obvious?
They are interim feature testing results which get scratched
(scrollChecks is undefined) if they are equal. They are used
internally and indicate that the body or html is the element holding
the appropriate client* properties. Ultimately, the result could be a
single flag as only mutually exclusive results are retained.

I see the mutually exclusive part. What is the reason for adding a 100px
div?
It certainly does NOT. Stop reading my comments about which browsers
have been observed to follow which forks and read the _logic_.
There's no "not IE" to it. In fact, as noted, IE is fine with either
of those two forks.

The comment says "This fork is for most modern non-IE browsers"

IE seems fine with that fork when in standards mode because of the
mutual exclusion.
http://groups.google.com/group/comp.../group/comp.lang.javascript/msg/ce4f73671872c...
[...]
http://www.w3.org/TR/cssom-view/
You are going on about nothing. That's not a standard either.
It is good indication of a forthcoming standard.
Doesn't matter in this case. Let IE adopt innerWidth/Height all they
want. See my other response.
In your existing code, IE <=8 gets the `else` branch. If IE9 implements
CSSOM Views innerHeight, then IE will get the first branch and will use
the scrollChecks object, possibly BODY for calculations when HTML should
be used instead.

You are dead wrong. Read the code again and realize IE will work with
either fork, whether it implements innerWidth/Height or not. And, as
mentioned, that extra innerWidth/Height stuff is likely unneeded at
this point. The verson in the FAQ completely _ignores_ those
properties anyway. So what are you trying to say?

OK, but IE *will* get the first fork when innerHeight is defined. It
seems that in that case, scrollChecks could either be an object or could
be undefined.

For quirks mode, I believe there is a case where IE would get
includeBordersInBody, and would then include document.body.clientTop * 2.

The code in the FAQ can fail when documentElement.clientWidth is !== 0,
but when documentElement.clientWidth is not the viewport width. That
case is shown in quirks mode, where documentElement.clientWidth can
measure the element width.

For example, when adding to the stylesheet:-

html, body {
height: 100%;
width: 100%;
}

document.documentElement.clientHeight == document.body.clientHeight

is going to be true in a lot of browsers.
You don't have to explain anything to me, except your assertion about
"offsetParent being BODY" for... what? You just want to talk about
something else (CSSOM I imagine).

The example answers that question. Here:

Make sense?
And _someone_ else. :)
What about someone else? And who?

The other problem with that change is that it makes complicates the code
with feature testing for such things.
I know. It's worthless at this point, particularly for this
discussion. Why you go on and on about it is beyond me? Are you
speaking to some other audience?

No, it is not worthless. It is good indication that what you are
filtering as "non-IE" will include IE. That was a poor inference for all
the reasons explained. CSSOM Views shows that that inference may fail IE9.
 
D

David Mark

David said:
David Mark wrote:
David Mark wrote:
David Mark wrote:
FAQ server wrote:
-----------------------------------------------------------------------
FAQ Topic - How do I find the size of the window?
-----------------------------------------------------------------------
[...]
[...]
[...]
http://www.cinsoft.net/viewport.asp
Took quick look at that.
| Some older KHTML-based browsers (e.g. Safari 2) feature
| document.clientHeight/Width properties. These properties are arguably
| a better alternative to measuring elements, but are apparently no
| longer in production.
document.clientWidth measures the viewport, not elements.
That's exactly what I said.  I use them instead of measuring elements
(when they are featured).
Ah, it seems the wording is not so good.
I guess.
It could seem like a better alternative to measure elements would be
document.clientHeight. When the goal is not measuring elements, but
measuring the viewport.
I don't care for that wording either.
It was not a suggestion. What you wrote is ambiguous; it leaves open for
possible interpretation that the author's goal is measuring elements.
The scrollChecks function is not very clear. It returns either an object
or undefined. It seems to be a feature test function, but I don't
understand the strategies it is using.
It's just creating an object to house various properties.  Yes, it is
a feature test.
| scrollChecks = (function()
|   var oldBorder, body = doc.body,
| result = { compatMode: doc.compatMode };
|   var clientHeight = html.clientHeight,
| bodyClientHeight = body.clientHeight;
|   var elDiv = doc.createElement('div');
|   elDiv.style.height = '100px';
|   body.appendChild(elDiv);
|
|   // (GS) What is the reason for `clientHeight != html.clientHeight`?
|   result.body = !clientHeight || clientHeight != html.clientHeight;
|   // (GS) What is the reason for this?
|   result.html = bodyClientHeight != body.clientHeight;
What does appending a 100px div to body have to do with
html.clientHeight? Or body.clientHeight?
Didn't want to answer?
See the post a minute later.  You hid those questions.
No, that is not true.
It doesn't matter what your intent was.  The end result is that they
were buried in my cited code (where I wouldn't expect to find your
inline comments buried without white space to set them apart).

I often leave initial in comment for line-by-line. Example:

| // (GS) What is this line for?

I could add a preceeding line break. What else would make line-by-line
comment more obvious?
They are interim feature testing results which get scratched
(scrollChecks is undefined) if they are equal.  They are used
internally and indicate that the body or html is the element holding
the appropriate client* properties.  Ultimately, the result could be a
single flag as only mutually exclusive results are retained.

I see the mutually exclusive part. What is the reason for adding a 100px
div?

It's only three or four lines, IIRC. It should be obvious that it is
looking for changes (or the lack thereof) in clientHeight.
The comment says "This fork is for most modern non-IE browsers"

So what? It should more accurately read: is _followed by_ most
modern... It's just an observation and has nothing to do with the
logic (obviously) as it forks based on the detection of a feature, not
a browser.
IE seems fine with that fork when in standards mode because of the
mutual exclusion.

Why on earth would you qualify that with "in standards mode". I've
tested it in both. In fact, I recently combined the two forks and
everything is fine in both modes.
http://groups.google.com/group/comp.lang.javascript/msg/6bc787294a819.......
[...]
http://www.w3.org/TR/cssom-view/
You are going on about nothing.  That's not a standard either.
It is good indication of a forthcoming standard.
Doesn't matter in this case.  Let IE adopt innerWidth/Height all they
want.  See my other response.
In your existing code, IE <=8 gets the `else` branch. If IE9 implements
CSSOM Views innerHeight, then IE will get the first branch and will use
the scrollChecks object, possibly BODY for calculations when HTML should
be used instead.
You are dead wrong.  Read the code again and realize IE will work with
either fork, whether it implements innerWidth/Height or not.  And, as
mentioned, that extra innerWidth/Height stuff is likely unneeded at
this point.  The verson in the FAQ completely _ignores_ those
properties anyway.  So what are you trying to say?

OK, but IE *will* get the first fork when innerHeight is defined.

That's fine.
It
seems that in that case, scrollChecks could either be an object or could
be undefined.

Yes, of course. And that is accounted for.
For quirks mode, I believe there is a case where IE would get
includeBordersInBody, and would then include document.body.clientTop * 2.

The code in the FAQ can fail when documentElement.clientWidth is !== 0,
but when documentElement.clientWidth is not the viewport width. That
case is shown in quirks mode, where documentElement.clientWidth can
measure the element width.

For example, when adding to the stylesheet:-

html, body {
   height: 100%;
   width: 100%;

}

That's a stretch, but okay...
document.documentElement.clientHeight == document.body.clientHeight

is going to be true in a lot of browsers.

....so what does that have to do with the border (or other) test?

if (typeof body.clientTop == 'number' && body.clientTop) {
oldBorder = body.style.borderWidth;
body.style.borderWidth = '0px';
result.includeBordersInBody = body.clientHeight !=
bodyClientHeight;
body.style.borderWidth = oldBorder;
}

Perhaps you misread?
The example answers that question. Here:


Make sense?

I saw that the first time. And no, it doesn't make particular sense
to me, but then I haven't thought about IE and the offsetParent of the
BODY element in quite a long time.
What about someone else? And who?

Who were you talking about?
The other problem with that change is that it makes complicates the code
with feature testing for such things.

The CSSOM change? I can certainly buy that. That's why I don't write
code that must measure the gap between the body's origin and the
viewport's.
No, it is not worthless. It is good indication that what you are
filtering as "non-IE" will include IE.

For God's sake. It's not filtered as non-IE (and you obviously know
that). It's filtered for the presence or absence of the innerWidth/
Height properties. And, as mentioned, IE will be fine if it ever
grows such properties. I have simplified the forking a bit in a new
version. The two forks followed by modern browsers (with clientWidth/
Height properties) are now one. The scrollChecks test was never meant
to be used with one fork and not the other. It was simply a late
addition and I forgot to copy it to the lower fork. It is also used
to determine which object holds the scroll position properties and has
proven successful at that as well.
That was a poor inference for all
the reasons explained. CSSOM Views shows that that inference may fail IE9..

No, you've repeated the same nonsense three times. There's no non-IE
inference and the code in the "non-IE" fork is perfectly appropriate
for IE (past, present and future). If you look at the two forks, it
is apparent that they do virtually the same thing (which is why I
ultimately combined them). Did you even read the code? It seems like
you just want to talk about my comment(s).

So anyway, the point is that this far superior to the version in the
FAQ. Some distillation may be necessary to shorten the length, which
is what I did in the example version. I propose to shorten it further
by removing that "contested" fork (no need to consider window.inner*
in the abridged version). That should put a stop to any speculation
about what IE may or may not do in it. Fair enough?
 
G

Garrett Smith

David said:
[...]
I often leave initial in comment for line-by-line. Example:

| // (GS) What is this line for?

I could add a preceeding line break. What else would make line-by-line
comment more obvious?

I see the mutually exclusive part. What is the reason for adding a 100px
div?

It's only three or four lines, IIRC. It should be obvious that it is
looking for changes (or the lack thereof) in clientHeight.

There will be no change in clientHeight in a common case:

css:
html, body {
height: 100%;
}

html:
<body>
<p>not much here.</p>
</body>

A difference would not be detected there.

Instead, consider appending a very large div (5000px). Large monitor
resolutions would be a problem, though I am unaware of any monitor with
even half that number of pixels.

A second potential problem could occur when calling this function before
page load.

In IE, Operation Aborted error will occur if appending the element to
BODY while body is being parsed.

This error can be avoided by using insertBefore firstChild:

body.insertBefore(elDiv, body.firstChild);
So what? It should more accurately read: is _followed by_ most
modern... It's just an observation and has nothing to do with the
logic (obviously) as it forks based on the detection of a feature, not
a browser.


Why on earth would you qualify that with "in standards mode". I've
tested it in both. In fact, I recently combined the two forks and
everything is fine in both modes.

In quirks mode it is possible to get bodyIncludesBorders =
true.

IE creates a shorthand value for inline style property, though that is
nonstandard.

[...]
Yes, of course. And that is accounted for.


That's a stretch, but okay...
It is very common to use:

html, body {
height: 100%;
}

to makes body and its 100% children fill the viewport area. It is a
solution to the question:

My div has height: 100%, but is not stretching to fill the window. What
is wrong?
...so what does that have to do with the border (or other) test?

if (typeof body.clientTop == 'number' && body.clientTop) {
oldBorder = body.style.borderWidth;
body.style.borderWidth = '0px';
result.includeBordersInBody = body.clientHeight !=
bodyClientHeight;
body.style.borderWidth = oldBorder;
}

Don't rely on reading shorthand values. Reading a shorthand value
will usually be empty string. When you set the border to an empty
string, well, obviously all border properties are removed.

Shorthand values are intransitive.

<body style="border-style: solid; border-width: 1px;">
<p>
<a href="#" onclick="getSetShowBorder()")>getSetShowBorder()</a>
</p>
<script type="text/javascript">
function getSetShowBorder(){
alert(document.body.style.border=document.body.style.border);
}
</script>
</body>

jQuery had the exact problem last year. That example code was the
example I emailed to John.

You could try a property that will be transitive. Either borderTopWidth,
or cssText would work.
Perhaps you misread?
Maybe.


I saw that the first time. And no, it doesn't make particular sense
to me, but then I haven't thought about IE and the offsetParent of the
BODY element in quite a long time.

Who were you talking about?
I mentioned Gerard Talbot, the one who filed the bug. I opposed the spec
and the validity of the bug in a bug comment. MS had the CSSOM Views
editor's draft at the time, not even a working draft, but went with
that. I had probably 30 or so messages on the w3c css mailing list,
explaining the ramifications of this mistake.
The CSSOM change? I can certainly buy that. That's why I don't write
code that must measure the gap between the body's origin and the
viewport's.

When trying to measure between element and parent, the body may be the
parent. CSSOM makes it necessary to special case BODY.

Having a "magic" root node is enough of a problem (overflow, border,
clientWidth)

Having magic BODY is quirks mode behavior. That is what your "getRoot"
function is trying to determine here. Well, for CSSOM, body is root
offsetParent, regardless of mode.

Anyway, that's a little off topic.

[...]
So anyway, the point is that this far superior to the version in the
FAQ. Some distillation may be necessary to shorten the length, which
is what I did in the example version. I propose to shorten it further
by removing that "contested" fork (no need to consider window.inner*
in the abridged version). That should put a stop to any speculation
about what IE may or may not do in it. Fair enough?

Right. Removing innerWidth test there seems like a good move.

The FAQ example can fail in quirks mode, and it doesn't try to account
for the root element borders.

Then again, I'm not sure that element borders should be accounted for.
If the goal is to add an overlay to body, and body has height: 100%,
you'd want the dimension to exclude the border, right?
 
D

David Mark

David said:
David Mark wrote:
David Mark wrote:
David Mark wrote:
David Mark wrote:
FAQ server wrote:
[...]


It's just creating an object to house various properties.  Yes,it is
a feature test.
| scrollChecks = (function()
|   var oldBorder, body = doc.body,
| result = { compatMode: doc.compatMode };
|   var clientHeight = html.clientHeight,
| bodyClientHeight = body.clientHeight;
|   var elDiv = doc.createElement('div');
|   elDiv.style.height = '100px';
|   body.appendChild(elDiv);
|
|   // (GS) What is the reason for `clientHeight != html.clientHeight`?
|   result.body = !clientHeight || clientHeight != html.clientHeight;
|   // (GS) What is the reason for this?
|   result.html = bodyClientHeight != body.clientHeight;
What does appending a 100px div to body have to do with
html.clientHeight? Or body.clientHeight?
Didn't want to answer?
See the post a minute later.  You hid those questions.
No, that is not true.
It doesn't matter what your intent was.  The end result is that they
were buried in my cited code (where I wouldn't expect to find your
inline comments buried without white space to set them apart).
I often leave initial in comment for line-by-line. Example:
| // (GS) What is this line for?
I could add a preceeding line break. What else would make line-by-line
comment more obvious?
What do scrollChecks.body and scrollChecks.html mean?
They are interim feature testing results which get scratched
(scrollChecks is undefined) if they are equal.  They are used
internally and indicate that the body or html is the element holding
the appropriate client* properties.  Ultimately, the result could be a
single flag as only mutually exclusive results are retained.
I see the mutually exclusive part. What is the reason for adding a 100px
div?
It's only three or four lines, IIRC.  It should be obvious that it is
looking for changes (or the lack thereof) in clientHeight.

There will be no change in clientHeight in a common case:

It's hardly a common case, but it works all the same. ;)
css:
html, body {
   height: 100%;

}

Good! Then it will fallback to the old compatMode solution.
html:
<body>
   <p>not much here.</p>
</body>

A difference would not be detected there.

What are you talking about? With the wacky styles above? Wouldn't
matter anyway (see above).
Instead, consider appending a very large div (5000px). Large monitor
resolutions would be a problem, though I am unaware of any monitor with
even half that number of pixels.

Unnecessary. In fact, to remove any confusion, I'm changing it to
1px. ;)
A second potential problem could occur when calling this function before
page load.

Obviously that's a non-issue. Such a function shouldn't even be
_defined_ until page load (and it isn't in the example).
In IE, Operation Aborted error will occur if appending the element to
BODY while body is being parsed.

Duh. See above.
This error can be avoided by using insertBefore firstChild:

body.insertBefore(elDiv, body.firstChild);

No good. You don't do things like this until the DOM is ready.
In quirks mode it is possible to get bodyIncludesBorders =
true.

Sure it is. That's why the test is there. ;) If you mean a false
positive, I don't think so. And the version in the FAQ doesn't even
consider this at all.
IE creates a shorthand value for inline style property, though that is
nonstandard.
So?
[...]


It
seems that in that case, scrollChecks could either be an object or could
be undefined.
Yes, of course.  And that is accounted for.
That's a stretch, but okay...

It is very common to use:

html, body {
   height: 100%;

}

Very common?! Get real.
to makes body and its 100% children fill the viewport area. It is a
solution to the question:

My div has height: 100%, but is not stretching to fill the window. What
is wrong?

Duh. If you are using such an idiotic strategy to "maximize" an
element, you don't need this script anyway.
Don't rely on reading shorthand values. Reading a shorthand value
will usually be empty string. When you set the border to an empty
string, well, obviously all border properties are removed.

I know. I made a mental note to change that to use the top border
width. It's changed in the latest version. I'll post it once I
finish testing with frames.
Shorthand values are intransitive.

<body style="border-style: solid; border-width: 1px;">
   <p>
     <a href="#" onclick="getSetShowBorder()")>getSetShowBorder()</a>
   </p>
<script type="text/javascript">
function getSetShowBorder(){
   alert(document.body.style.border=document.body.style.border);}

</script>
</body>

jQuery had the exact problem last year. That example code was the
example I emailed to John.

Who cares?
You could try a property that will be transitive. Either borderTopWidth,
or cssText would work.
Obviously.


Maybe.

Seems that way. :)

[...]
Right. Removing innerWidth test there seems like a good move.

The FAQ example can fail in quirks mode, and it doesn't try to account
for the root element borders.

Then again, I'm not sure that element borders should be accounted for.
If the goal is to add an overlay to body, and body has height: 100%,
you'd want the dimension to exclude the border, right?

The borders are included/excluded with a feature test. I think the
test speaks for itself. The borders are included in some older Opera
versions/modes. This is explained in the document.
 
D

David Mark

[...]
The borders are included/excluded with a feature test.  I think the
test speaks for itself.  The borders are included in some older Opera
versions/modes.  This is explained in the document.

Update. Garrett did have one correct point. In _quirks mode_ in IE,
if it uses the scrollChecks test results (which it is supposed to be
doing), the borders are incorrectly figured in. This is not apparent
at the moment due to the extraneous fork for browsers without
innerWidth/Height properties.

Why did the border test fail? Because IE actually uses the body as
the root (as opposed to reporting the HTML element's clientWidth/
Height). So the border of the body is actually the border of the
viewport.

I did update the test (and a few comments). It's simply a matter of
skipping the border check if the HTML element isn't rendered (as in IE
quirks mode). The border test cannot work in that case (and obviously
isn't needed). Also fixed a typo (present in both the example and the
long version), but it was related to frames (rendering mode mismatch),
so was not apparent either. Will post a re-vamped (and slightly
longer) version with support for frame mismatches when I get a chance
to finish testing it.

The silly 100% heights (for both body and HTML) work fine though. But
that's a moot point as it is an alternative (bad) strategy for
maximizing elements.

So where is everyone else on this issue? Anyone else have anything to
say? Any failures to report? Successful results aren't of much
interest, but I have tested in all of the major browsers (current and
some past versions).

It would be good to get a basic consensus and distilled version for
the FAQ. Most of the rest of the world is still sniffing the UA
string to "solve" this problem (see YUI, Goog, Prototype, etc.) I
can't understand why they didn't use the old FAQ version from 2001.
It wasn't perfect, but at least it wasn't browser sniffing. ;)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,962
Messages
2,570,134
Members
46,690
Latest member
MacGyver

Latest Threads

Top