4

I need to size a vertical range control based on the available height in the browser. I just about have it, except I think there is some type of a padding/border/margin issue that I can't get around. Although it sizes itself according to the height of the browser, my range control always goes off the bottom of the page by a few pixels.

This is how I'm getting the height:

var height = window.innerHeight 
|| document.documentElement.clientHeight
|| document.body.clientHeight;

then using it to set the slider height:

document.getElementById("slider").setAttribute('style', "height :" + height + "px");

I know that clientHeight returns the height INCLUDING padding, so I've been thinking that I just need to get the top padding and subtract it. Problem is that when I get the padding as shown here, it is zero (alert writes out 0px):

alert("top pad: " + window.getComputedStyle(document.documentElement, null).getPropertyValue('padding-top'));

Meanwhile, the CSS for the slider looks like this, so I don't think its own padding/border/margins are responsible:

.sliderStyle {
    height: 860px;
    width: 2%;
    -webkit-appearance: slider-vertical;
    padding-top: 0px;
    margin: 0px;
    border: 0px;
}

The only thing in the body of the HTML is the range control:

<input id="slider" class="sliderStyle"  oninput='' onchange='' type="range"  min="0" max="1000" step="1" value="0"> 

Here is the file in its entirety:

<!DOCTYPE html>
<html>
    <head>
        <title>Size Control to Browser</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
                <style type="text/css" media="screen">
            .sliderStyle {
                height: 860px;
                width: 2%;
                -webkit-appearance: slider-vertical;
                padding-top: 0px;
                margin: 0px;
                border: 0px;
            }
       </style>

    <script type="text/javascript">
            function start() {
                var height = window.innerHeight
                                || document.documentElement.clientHeight
                                || document.body.clientHeight;
               alert('clientHeight: ' + height);
               alert("top pad: " + window.getComputedStyle(document.documentElement, null).getPropertyValue('padding-top'));
               alert("top margin: " + window.getComputedStyle(document.documentElement, null).getPropertyValue('margin-top'));
               document.getElementById("slider").setAttribute('style', "height :" + height + "px");
          }

    </script>
    </head>
<body onload='start()'>
    <input id="slider" class="sliderStyle"  type="range"  min="0" max="1000" step="1" value="0"> 
</body>
</html>

clientHeight alert confirms that height is changing for different browser sizes
top pad and top margin alerts both return 0px

Larry Holze
  • 365
  • 1
  • 4
  • 7
  • Oh - and I am not using jQUery - just straight Javascript – Larry Holze May 10 '15 at 04:55
  • would need more info but... maybe wrap another div around it and use it's height? – mike May 10 '15 at 05:46
  • Thanks mike - What other info would you need? I've edited to include the entire file. Wrapping it in a div presents the same issue: need to first size the div to fit exactly in the client area, and it does not. Goes off bottom a little just like the range control. – Larry Holze May 10 '15 at 14:49
  • `alert("top margn: " .......getPropertyValue('margin-top'));` `padding` or `margin`? – el Dude May 10 '15 at 15:44
  • el Dude - I'm afraid I don't understand what you are asking. There are two separate alerts: one for the padding and one for the margin. Thanks – Larry Holze May 10 '15 at 15:48
  • ed Dude - Sorry, i see what you mean: I was talking about padding but pasted in the alert line for margin. I've corrected. Full code has both. – Larry Holze May 10 '15 at 15:56
  • If you want it to be the full height of the ``, then why not just set the height, in CSS, to [`99vh`](http://jsfiddle.net/davidThomas/s2140egg/)? `100vh` would be the *full* height, but even with `margin: 0; padding: 0` on `html`, `body` and the `input` that still leads to some over-flow (possibly due to nature of the range-input). Unfortunately, as `vh` is a percentage of viewport-height (`1vh` equal to `1%` of the viewport's height) in a long document that goes below the fold `100vh` will still only be the height of the viewport, *not* the document. – David Thomas May 10 '15 at 16:01

1 Answers1

0

To answer your question: use the below JavaScript as your height variable, instead of using clientHeight or innerHeight (and set the body to be 100vh). (See the jsfiddle):

JS:

var style = window.getComputedStyle(document.body, null),
    height = style.getPropertyValue("height");

console.log(height);

CSS:

body {
    padding: 20px;
    height: 100vh;
}

div {
    height: 30px;
}

HTML:

<div></div>

What the code does is gets the height of contents of the body, which in essence is the height of the body without any padding.

The only reason I put a random div element in there with a set height of 30px is to show that console.log(height) will output exactly 30px, which is the height of all the contents in the body (in this case, the div is the only thing in the body), not including the padding of the body (which, according to the example CSS I used above, is 20px). You can obviously just remove this div, as it is just here for example purposes.

The JavaScript is taken from this answer to "Get the height of an element minus padding, margin, border widths", which also shows a legacy cross-browser implementation.

Community
  • 1
  • 1
Josh Beam
  • 19,292
  • 3
  • 45
  • 68
  • client height and body height are two different things. The body can be set to 10px high if we wanted to and in many cases it is longer than the client height. – GillesC May 10 '15 at 16:18
  • @gillesc, yeah, true, thanks for pointing that out. I've changed the code to add `100vh` as the body height. Would that fix what you're talking about? – Josh Beam May 10 '15 at 16:24
  • Thanks Josh, but when I tested this answer, I got the same result as my original. Looks like the viewport height (vh) includes the padding. If it was the height EXcluding padding, height as calculated in the answer would decrease as body padding increases, but it doesn't. Returned height as calculated in the answer does not change as body padding changes. – Larry Holze May 10 '15 at 17:33
  • @LarryHolze, ok I see, I misunderstood the issue. I will re-work the solution. – Josh Beam May 10 '15 at 17:59