Getting an elements height

M

Mark Smith

Is there a way to find out the height of a specified element, that
will work even when display is set to "none"?

I.e a div element is hidden, but I want to know how tall it will be
when it is shown.

Thanks
 
E

Evertjan.

Mark Smith wrote on 05 jan 2009 in comp.lang.javascript:
Is there a way to find out the height of a specified element, that
will work even when display is set to "none"?

I.e a div element is hidden, but I want to know how tall it will be
when it is shown.

show > measure > hide

The use will not notice 99 out of 100 times.
 
T

Thomas 'PointedEars' Lahn

Mark said:
Is there a way to find out the height of a specified element, that
will work even when display is set to "none"?
I.e a div element is hidden, but I want to know how tall it will be
when it is shown.

1. Set .style.visibility to "hidden".
2. Set .style.display to "" (or "block", or whatever).
3. Read and store .offsetHeight (watch for differences in box model).
4. Set .style.display back to "none".
5. Set .style.visibility back to "visible".


HTH

PointedEars
 
D

Dan Evans

1. Set .style.visibility to "hidden".
2. Set .style.display to "" (or "block", or whatever).
3. Read and store .offsetHeight (watch for differences in box model).
4. Set .style.display back to "none".
5. Set .style.visibility back to "visible".

If the purpose of setting visibility to "hidden" in step 1 is to not
show the element to the user then this may not fully accomplish that
goal. I would suggest another step in addition to those above:

1.5. Set .style.position to "absolute".
....
6. Set .style.position back to whatever it was before.

It might be worth storing the original value of .style.position if
this is a function called on arbitrary objects where the value may
vary.

Dan Evans
 
T

Thomas 'PointedEars' Lahn

Dan said:
If the purpose of setting visibility to "hidden" in step 1 is to not
show the element to the user then this may not fully accomplish that
goal.

Why not, except in a completely borken UA (that I have yet to see)?
I would suggest another step in addition to those above:

1.5. Set .style.position to "absolute".

Utter nonsense. Setting .position="absolute" will compute wrong values for
offsetHeight.

And what for? BTW, .position="absolute" (followed by .top="-9999px" and the
like) is but a poor substitute for .visibility="hidden" or .display="none",
as frequently seen in scriptkiddie libraries.
....
6. Set .style.position back to whatever it was before.

What would setting .position="absolute" would accomplish that
visibility="hidden" would not accomplish anyway?
It might be worth storing the original value of .style.position if
this is a function called on arbitrary objects where the value may
vary.

Pardon? Even if it was a function called on arbitrary objects, the
execution context would not be left until the last statement was executed,
and the local variable would make sure that even if seemingly parallel
processing was performed (with setTimeout(); ECMAScript implementations so
far are single-threaded), declaring the storing variable makes sure its
scope does not extend beyond its execution context. It is unlikely that
setting back the property value would take as long as leaving the execution
context and entering another one.


PointedEars
 
B

Ben Amada

Utter nonsense.  Setting .position="absolute" will compute wrong values for
offsetHeight.

And what for?  BTW, .position="absolute" (followed by .top="-9999px" and the
like) is but a poor substitute for .visibility="hidden" or .display="none",
as frequently seen in scriptkiddie libraries.


What would setting .position="absolute" would accomplish that
visibility="hidden" would not accomplish anyway?

Setting position to absolute as Dan recommends accomplishes taking the
element out of the document flow so surrounding elements are not very
momentarily shifted when the display style changes from hidden to
block. Setting visibility to hidden doesn't take the element out of
the document flow and risks the very minimal chance the user sees a
flicker when display is set to block.

The sample below demonstrates this. In FF3, IE7, Safari and Chrome,
setting position to absolute will take the div out of the document
flow and offsetHeight returns the same value regardless if position is
set to absolute. You can see the difference setting position to
absolute makes by running the code once with "d.style.position =
'absolute'" commented out, and running it again with that line
uncommented.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script type="text/javascript">
function checkHeight() {
var d = document.getElementById('divThis');
// uncomment line below so bottom div is not
// shifted during first alert
//d.style.position = 'absolute';
d.style.visibility = 'hidden';
d.style.display = '';
var iHeight = d.offsetHeight;
alert('intentional pause ...');
d.style.display = 'none';
d.style.visibility = 'visible';
d.style.position = '';
alert(iHeight);
return false;
}
</script>

</head>
<body>

<div style="height:50px;background-color:red;">
stuff ...
<input type="button" onclick="return checkHeight()"
value="Check Height" />
</div>
<div id="divThis" style="background-color:green;display:none;">
test<br />
test<br />
test<br />
test<br />
</div>
<div style="background-color:eek:range;">
more stuff ...
</div>

</body>
</html>
 
L

Logos

Setting position to absolute as Dan recommends accomplishes taking the
element out of the document flow so surrounding elements are not very
momentarily shifted when the display style changes from hidden to
block.  Setting visibility to hidden doesn't take the element out of
the document flow and risks the very minimal chance the user sees a
flicker when display is set to block.

The sample below demonstrates this.  In FF3, IE7, Safari and Chrome,
setting position to absolute will take the div out of the document
flow and offsetHeight returns the same value regardless if position is
set to absolute.  You can see the difference setting position to
absolute makes by running the code once with "d.style.position =
'absolute'" commented out, and running it again with that line
uncommented.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script type="text/javascript">
  function checkHeight() {
    var d = document.getElementById('divThis');
        //   uncomment line below so bottom div is not
        //   shifted during first alert
        //d.style.position = 'absolute';
        d.style.visibility = 'hidden';
        d.style.display = '';
        var iHeight = d.offsetHeight;
        alert('intentional pause ...');
        d.style.display = 'none';
        d.style.visibility = 'visible';
        d.style.position = '';
        alert(iHeight);
        return false;
  }
</script>

</head>
<body>

<div style="height:50px;background-color:red;">
  stuff ...
  <input type="button" onclick="return checkHeight()"
    value="Check Height" />
</div>
<div id="divThis" style="background-color:green;display:none;">
 test<br />
 test<br />
 test<br />
 test<br />
</div>
<div style="background-color:eek:range;">
 more stuff ...
</div>

</body>
</html>

Couldn't you reduce flicker by giving it a margin of say a 5000px
while you're evaluating it, forcing it to render off the browser
window area?
 
B

Ben Amada

Couldn't you reduce flicker by giving it a margin of say a 5000px
while you're evaluating it, forcing it to render off the browser
window area?

That might result in a horizontal scrollbar popping up if there's an
element way off to one side -- but I don't know without testing it.
Setting position to absolute eliminates any potential flicker.
 
T

Thomas 'PointedEars' Lahn

Ben said:
Setting position to absolute as Dan recommends accomplishes taking the
element out of the document flow so surrounding elements are not very
momentarily shifted when the display style changes from hidden to
block. Setting visibility to hidden doesn't take the element out of
the document flow and risks the very minimal chance the user sees a
flicker when display is set to block.

Ah, *that*. OK.

However, ISTM this argument it is based on the assumption that no other
elements in the relevant sub-tree are positioned absolute or relative.
Which can *not* be assumed.
offsetHeight returns the same value regardless if position is
set to absolute.

From a very superficial test, I can confirm this for Firefox 3.0.5/Gecko
1.9.0.5, which I find rather surprising.


PointedEars
 
G

Gregor Kofler

Thomas 'PointedEars' Lahn meinte:
Ben Amada wrote:

From a very superficial test, I can confirm this for Firefox 3.0.5/Gecko
1.9.0.5, which I find rather surprising.

I've used this "practice" on a few occassions for the same purpose as
the OP, and haven't encountered any differing values so far. (But then
it was used or tested only with few different element types and only in
HTML 4 strict documents.)

Gregor
 
T

Thomas 'PointedEars' Lahn

Gregor said:
Thomas 'PointedEars' Lahn meinte:

I've used this "practice" on a few occassions for the same purpose as
the OP, and haven't encountered any differing values so far. (But then
it was used or tested only with few different element types and only in
HTML 4 strict documents.)

Thanks. The part of Ben's explanation that I find questionable, though, is
that position:absolute would take the element out of the element flow and
thus flickering could be avoided. position:absolute certainly can have the
described effect, but that is not what it means. Instead, it positions the
element absolute in relation to the next ancestor that is positioned (has
position != static), or the viewport if there is no such element. IOW, with

<div style="position: absolute">
<div id="foo">
...
</div>
</div>

or

<div style="position: relative">
<div id="foo">
...
</div>
</div>

setting position:absolute on the `div' element with ID `foo' would still
allow flickering.

(In order to take an element out of the normal element flow, you have to set
its `float' property to a value different than `none' instead.)


PointedEars
 

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
474,123
Messages
2,570,740
Members
47,296
Latest member
EarnestSme

Latest Threads

Top