I have a piece of JS code that determines whether there is a vertical scrollbar and applies a CSS class to an element. Nothing big.
What is confusing me is it appears to be doing the opposite of what I understand it should be doing. This isn't a problem unless it is a bug and is fixed in the future.
The code:
if (document.body.scrollHeight > document.body.clientHeight) {
var d = document.getElementById("footer").className = "footernoscroll";
}
My understanding is that it will apply the class if there is a vertical scroll bar, but it appears to be applying the class if there isn't a scroll bar. Am I interpreting this correctly and the code is acting strangely or is my interpretation wrong?
EDIT: Thought I should add, if I reverse the operator the effects will be reversed and it will use the else part of the statement instead.
Make sure that your body is 100% of the window height. If you don't have this then the clientHeight value will be the combined height of the items within body and not the full window height, whereas scrollHeight will be the full height of the window.
Here's a fiddle that shows it working (open dev tools and view console): http://jsfiddle.net/alexcoady/c53d7q27/1/
html, body {
height: 100%;
padding: 0;
margin: 0;
}
clientHeight documentation
scrollHeight documentation
The scrollHeight value is equal to the minimum clientHeight the element would require in order to fit all the content in the viewpoint without using a vertical scrollbar.
Taken from here: https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight
So it means the values are the same if there is no scrollbar, and scrollHeight is greater when there is one.
Related
There are many ways of getting the height of a document, but due to different browser implementations most of them (I believe) return the highest of a number of values ... which is fine most of the time.
In my case I have a number of elements on the page that I know to be a smaller height than the window and viewport heights. What I'm trying to get is the actual height of all the rendered elements.
Things that don't work (with testing in Firefox):
$(document).height(); // gives the window height
document.body.scrollHeight; // gives 7, its always 7 I don't know why
document.body.offsetHeight; // also gives 7
document.documentElement.clientHeight; // sometimes gives window height
document.documentElement.scrollHeight; //gives window height
document.documentElement.offsetHeight; generally gives a value in the range of 23
At present I'm thinking that the way around this might be to insert a div with height: 0 at the bottom of my page and grab $(div).offset().top, but I feel that this is highly likely to go wrong at some point in the future.
So before I do that ...
Is there a way of knowing the content height when it's less than the window height?
EDIT:
People have asked for clarification. Heres a jsFiddle example of what I want / the results I'm getting.
https://jsfiddle.net/8Lu2zcw8/1/
Running that results in the same value for Win Height: and Doc Height being written out to the console.
EDIT2:
My issue was due to the body not wrapping the content correctly due to floated and absolutely positioned elements, as pointed out by #tim-vermaelen in the comments to his solution.
I suggest you use $(document.body).height().
In CSS you have to put:
html,
body { height: 100%; }
This will only give correct results in case of body padding, margin and borders of the body element are 0. When direct children are floating or put on position absolute, the height of these elements doesn't count. Hence for floating elements you always clearfix the parent to solve these wrapping issues.
If not you can use $(document.body).outerHeight(includeMargin)
$(document).height() will give you content size, not window's. If it gives you window's size, then you probably messed up your CSS. Also, you can try $('body').height()
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).
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.
I have this jsfiddle http://jsfiddle.net/r3pek/wxffL/ where i'm trying to understand why does the scroll goes beyond de window size :/
If I remove the "height: 100%" from the rightpane class, I don't have a scroll; if I add it, I have a scroll but that goes beyond the window. Any way I can limit the scroll to the window?!
Thanks in advance!
EDIT:
Just a quick update...
I updated the fiddle to reflect the actual problem. I have an image that takes space as a header and it looks like that image size isn't accounted for. (I really suck at CSS :P )
You have to define a height for an element to scroll. That's why the scrollbar disappears when you remove the height. You're also adding padding to the div along with the 100% height. That adds to the element's height so it ends up being taller than the window. Reduce the height to something less than 100%, maybe 90% and play with it. That will allow you to keep the scrollbar and keep it inside the window. I have a fiddle set up for you here.
The total height (or "outer height") of an element equals inner height (which you can specify in css) + padding + border.
If you use height: 100% but then also add padding and/or borders then the total height will be bigger than 100%. There's a css property called box-sizing that can help you but it's not cross-broswer (you guessed it, IE<9).
If you drop the borders and paddings, it'll be fixed. But then to have borders and padding on outer elements... you'll need to get creative (or come back here with a specific question)
OK, I solved the problem, just not sure if it was the "right way". Anyway, here's how I did it:
added this right before the tag:
<script>
window.onload=setRightPaneHeight;
</script>
Then, I created the function that will calculate the right size for the "rightpane":
function setRightPaneHeight(){
var pic = document.getElementById("headerPic");
var pic_h = pic.offsetHeight;
var total_h = window.innerHeight;
var right_pane = document.getElementById("rightpane")
$(".rightpane").height(total_h - pic_h - 30);
}
That being done, now after the page loads, the right height is calculated for the rightpane DIV. And it works :)
Thanks for all the answers as they made me understand what the problem was!
I need help with this two elements properties.
According MDN element.scrollHeight "this a height of the scroll view of an element; it includes the element padding but not its margin", and element.offsetHeight "Typically, an element's offsetHeight is a measurement which includes the element borders, the element vertical padding, the element horizontal scrollbar (if present, if rendered) and the element CSS height."
I am trying to debug some javascript code and don't understand why document.body.scrollHeight can be greater than document.body.offsetHeight?
For example, my document.body.offsetHeight=909, but document.body.scrollHeight=1059 (body don't have any margins or paddings or borders), so we lost 150px somewhere. I inspected body and it height=909, and this is very confuse me. This reproduced in chrome and firefox.
Can you please help me in this question?
The offsetHeight property describes how far from the top of the current available space in the active window. The scrollHeight property is how far in pixels from the inside top of a contain to the inside bottom, which is different than clientHeight on a container set to a limited height with overflow:scroll css property.
I am using most of these in project I am working on at http://prettydiff.com/jsgui/
I have a page made of elements with width and height set to auto and their dimensions defined with left, right, top and bottom properties. When the page is loaded, all widths and heights are set to their calculated values by the browser, as they should be. However, when I set min-width of the elements to their respective calculated widths, each of those elements is expanded by 2px. The same happens if I set their min-height to be equal to the calculated height. I do it with jQuery, like this
element.css('min-width', element.css('width'));
or
element.css('min-width', element.width());
The effect is exactly the same as it should be, but there should not be the extra 2px if I understand what's happening correctly. Using
element.css('min-width', element.width() - 2);
completely solves the problem but I don't like not understanding why there are the extra 2px. According to specifications, neither width nor min-width nor max-width should include padding, borders or margins.
I've tested in Chrome and FF and both behave the same way.
What browser are you testing and can it be that your document is in quirksmode?
element.css('min-width', element.width()); shouldn't be doing anything in standards mode, because element.width() returns an integer without a CSS unit, and min-width requires a unit in standardsmode.
So put your document in standards mode and then try:
element.css('min-width', element.width() + "px");
If that doesn't help you'll need to show a working example.