8

Ok, I was going to answer someone's question here on SO about why their script wasn't working. They loaded content into a hidden div, then got the height so they could animate the wrapping div. But I always try to test the code I provide. So I made this demo to prove it to them.

So, umm, have I entered the twilight zone or am I dreaming right now? pinches self OUCH!

I tried that demo in Firefox, IE and Chrome and both methods return the same value. Firebug says zero! I rebooted my computer and I even changed the code a bit (removed the height function) and tried it with jQuery 1.3.2 and it still worked! I know hidden elements USED to return a zero value. Even this SO Answer is giving the advice I would have!

So I guess my question is... did I miss something or are we giving bad advice?

Community
  • 1
  • 1
Mottie
  • 84,355
  • 30
  • 126
  • 241

4 Answers4

11

Looking at the jQuery 1.4.2 and 1.3.2 source code, it actually performs this automatically when you call width() or height() on a hidden element. It sets the following attributes:

{ position: "absolute", visibility: "hidden", display:"block" }

Then it gets the width/height, and restores the old values of the attributes.

So there is no need to change the attributes yourself - jQuery will handle it for you.

<Edit>
This will allow you to get the dimensions of a hidden element. However, it won't work when the element is contained within another hidden element - you'll get a height of 0. In that case you'd need another solution, possibly like this answer.
</Edit>


Here are the relevant bits of the source code from 1.4.2:

cssShow = { position: "absolute", visibility: "hidden", display:"block" },

//[undocumented jQuery.css function which is called by .height() and .width()]
css: function( elem, name, force, extra ) {
    if ( name === "width" || name === "height" ) {
        var val, props = cssShow, ....

        function getWH() {
            ... this function gets the actual width/height into the variable val
        }

        if ( elem.offsetWidth !== 0 ) {
            getWH();
        } else {
            jQuery.swap( elem, props, getWH );
        }

        return Math.max(0, Math.round(val));
    }
    return jQuery.curCSS( elem, name, force );
},

// A method for quickly swapping in/out CSS properties to get correct calculations
swap: function( elem, options, callback ) {
    var old = {};

    // Remember the old values, and insert the new ones
    for ( var name in options ) {
        old[ name ] = elem.style[ name ];
        elem.style[ name ] = options[ name ];
    }

    callback.call( elem );

    // Revert the old values
    for ( var name in options ) {
        elem.style[ name ] = old[ name ];
    }
}
Community
  • 1
  • 1
interjay
  • 107,303
  • 21
  • 270
  • 254
  • Nice thanks! I guess I could have dug through the code, but I didn't think 1.3.2 already had implemented this code. I guess I need to update my advice :) – Mottie May 19 '10 at 00:06
  • Thanks for the update, but the problem with appending the element to the end of the body is if the parent element has a size restriction, say a width setting, this won't get applied to the cloned element so the height value would be completely off. Oh well, something to think about. – Mottie May 19 '10 at 16:14
1

I ran into the same problem with getting hidden element width, so I wrote this plugin call jQuery Actual to fix it. Instead of using

$('#some-element').height();

use

$('#some-element').actual('height');

will give you the right value for hidden element or element has a hidden parent.

You can also use

// get hidden element actaul width
$( '.hidden' ).actual( 'width' );

// get hidden element actaul innerWidth
$( '.hidden' ).actual( 'innerWidth' );

// get hidden element actaul outerWidth
$( '.hidden' ).actual( 'outerWidth' );

// get hidden element actaul height
$( '.hidden' ).actual( 'height' );

// get hidden element actaul innerHeight
$( '.hidden' ).actual( 'innerHeight' );

// get hidden element actaul outerHeight
$( '.hidden' ).actual( 'outerHeight' );

Full documentation please see here. There is also a demo include in the page.

Hope this help :)

Community
  • 1
  • 1
ben
  • 1,525
  • 2
  • 15
  • 15
0

You can also use the javascript's scrollHeight attribute.

$("#id_element").attr('scrollHeight')
QuarK
  • 2,306
  • 1
  • 20
  • 24
0
$('.hidden-element').get(0).height;

gives the height from DOM element, which is set also fro hidden elements

Luca C.
  • 11,714
  • 1
  • 86
  • 77