8

Using either plain Javascript or jQuery, I need to get the full height of a scrolling element. But the DOM property scrollHeight is apparently not 100% reliable.

I was envisioning temporarily giving the item a css height of auto, checking out its size, then returning the css to its prior value (which itself has problems--how do I get the css height:100% instead of height:1012px like jQuery .css('height') will return). But then I figured out that due to the way jQuery applies css styling directly to an element, simply applying the style '' returns it to its normal style-sheet-declared value, so theoretically I could do this:

$el.css('height', 'auto');
scrollHeight = $el.height();
$el.css('height', '');

But this isn't working. height:auto isn't overriding my element's original style of 100% and making the element take up its full desired height.

So now I'm thinking something more along these lines: use the position of the first child element's top and the position of the last child element's bottom to get the height. (I can adjust for padding and margin if necessary, this is just a proof of concept.)

function scrollHeight($el) {
   var lastEl = $el.children(':last');
   return (
      lastEl.position().top
         + lastEl.height()
         - $el.children(':first').position().top;
   );
}

Some working in of Math.max($el[0].scrollHeight, $el.height()) could also be useful...

Is that a terrible idea? I can't be the only person who's ever needed to know the scrollHeight of a DOM element and have it be reliable, not changing as the item is scrolled, and working in all major browsers, as well as IE 8 (though it would be interesting to know a solution for IE 6 & 7).

Community
  • 1
  • 1
ErikE
  • 48,881
  • 23
  • 151
  • 196
  • 1
    IE 6 and 7 ? even Google (yes, even on the white start page :)) dropped support to those two fellas – Roko C. Buljan Jul 17 '13 at 18:21
  • Could you provide a jsfiddle which reproduce your issue? – A. Wolff Jul 17 '13 at 18:22
  • @RokoC.Buljan That is a pretty good point. My own company only left IE7 within the last year... so that's why I was thinking I'd like to know how to support it, even if it's becoming scarce in the wild. But I'll update the question to reflect this. – ErikE Jul 17 '13 at 18:24
  • @roasted I guess one should always do that--I usually do! And it would have shown the problem because the element has absolutely positioned ancestors with `overflow` properties set that prevent it from taking its full height. Give me some time to update my question, please... – ErikE Jul 17 '13 at 18:36
  • @roasted Please see the comments on the accepted answer, which will explain the findings. You are 100% right that setting up an example would have forced me to go through the exercise of examining all the CSS closely as I stripped it down. – ErikE Jul 17 '13 at 18:41
  • glad you have found what was your issue :) – A. Wolff Jul 17 '13 at 18:42

1 Answers1

7

Instead of

$el.css('height', 'auto');

Try -

$el.attr('style', 'height: auto !important');

I mention trying this becuase you say -

height:auto isn't overriding my element's original style of 100% and making the element take up its full desired height.

Ross
  • 3,335
  • 1
  • 19
  • 18
  • 1
    Well, that does indeed show where the problem is. Due to ancestor elements being absolutely positioned with `height` and `overflow` values that prevent the child from taking its full height, even your updated suggestion won't work. Sorry for leaving that info out. A jsfiddle would have been a good idea. – ErikE Jul 17 '13 at 18:35
  • 1
    So using `.css('height', 'auto')` is going to work just fine. Your suggestion is excellent though and pointed me in the right direction: some pre-existing style was preventing `auto` from doing anything. That style was `bottom: 0; top: 0` which weren't even needed. I would say sorry for wasting your time, but it wasn't really a waste--you got 35 rep so far and helped me with my problem, plus I learned something. Thank you! – ErikE Jul 17 '13 at 18:41