40

How do you get an element's inner height, without padding and borders?

No jQuery, just pure JS, and a cross-browser solution (IE7 included)

enter image description here

Chuck Le Butt
  • 47,570
  • 62
  • 203
  • 289
vsync
  • 118,978
  • 58
  • 307
  • 400
  • 1
    Why not use `border-box` in css? That way you don't have to worry about these things... Then you can use `offsetHeight` which will return the proper height without the margin. – elclanrs Nov 17 '12 at 22:59
  • this is a very specific question for a plugin I make which has no CSS control, I just have to work with what I got – vsync Nov 17 '12 at 23:04
  • So...I guess you can still set the `box-sizing: border-box`, it'll save you some time and headaches. – elclanrs Nov 17 '12 at 23:06
  • I cannot, because my plugin runs on others' websites, which it is not up to me to change their CSS settings in any way that can harm the design – vsync Nov 17 '12 at 23:09
  • `element.style.boxSizing = 'border-box';` – uınbɐɥs Nov 17 '12 at 23:10
  • Don't know what kind of plugin is it but I don't see why you shouldn't use it only on that element, I mean you're not changing any CSS other than what's necessary for your plugin to work. – elclanrs Nov 17 '12 at 23:12
  • 4
    yes, BUT this css setting is not for old IE, and also, there might be other code that works with the webpage that might mis-calculate things if I start changing CSS. this is ALWAYS a bad idea. never change, only work with what you have when it's not your own webpage – vsync Nov 17 '12 at 23:17
  • Maybe you could clone the element, change the `box-sizing`, then calculate that? – uınbɐɥs Nov 17 '12 at 23:18
  • basically a good idea, BUT a very slow thing to do in my case, because i need it calculated on every scroll event. cloning will kill the performance of my plugin, which I am trying to improve. – vsync Nov 17 '12 at 23:20

5 Answers5

37
var style = window.getComputedStyle(document.getElementById("Example"), null);
style.getPropertyValue("height");

The above version will work in modern browsers. Please check currentStyle for IE browsers.

Rajkamal Subramanian
  • 6,884
  • 4
  • 52
  • 69
10

clientHeight - give the height including padding but without the borders.

getComputedStyle - a way to tap into the CSS rules of an element and retrieve a property's value (padding)

Using parseInt is a way to strip away units and leave only the numeric value (which is in pixels)
parseFloat can also be used for more precise sub-pixel measurements

Note that all values will automatically be converted by the DOM API to pixels

function getInnerHeight( elm ){
  var computed = getComputedStyle(elm),
      padding = parseInt(computed.paddingTop) + parseInt(computed.paddingBottom);

  return elm.clientHeight - padding
}

DEMO:

// main method
function getInnerHeight( elm ){
  var computed = getComputedStyle(elm),
      padding = parseInt(computed.paddingTop) + parseInt(computed.paddingBottom);
  
  return elm.clientHeight - padding
}

// demo utility function
function printInnerHeight( selector ){
  console.clear()
  console.log(
    getInnerHeight( document.querySelector(selector) )
  )
}
body{ display: flex; padding:0; margin: 0; }
div{ flex: 1; }

.demo1{
  padding-top: 2vh;
  padding-bottom: 1vh;
  margin: 30px;
  border: 10px solid salmon;
  box-sizing: border-box;
  outline: 1px solid red;
}

.demo2{
  padding-top: 2vh;
  padding-bottom: 4vh;
  margin: 30px;
  border: 10px solid salmon;
  border-bottom-width: 0;
  height: 150px;
  outline: 1px solid red;
}


p::before{
  content: '';
  display: block;
  height: 100%;
  min-height: 50px;
  background: lightgreen;
}
<div>
  <h2>inner height should be ~50px</h2>
  <button onclick="printInnerHeight('.demo1')">Get Inner Height</button>
  <p class='demo1'></p>
</div>
<div>
  <h2>inner height should be ~150px</h2>
  <button onclick="printInnerHeight('.demo2')">Get Inner Height</button>
  <p class='demo2'></p>
</div>
vsync
  • 118,978
  • 58
  • 307
  • 400
  • So, this words, but the `querySelector` should really be moved from `printInnerHeight` to `getInnerHeight` – Regular Jo Dec 31 '20 at 16:16
  • @RegularJoe - it doesn't. `getInnerHeight` accepts an argument which is the element to detect height, and it should have no notion of any existing DOM elements, and not work with any given visible element – vsync Dec 31 '20 at 16:39
2

EDIT from comments:

http://jsfiddle.net/hTGCE/1/ (a bit more code then expected)

in the internet you find functions like this:

  function getRectangle(obj) {

          var r = { top: 0, left: 0, width: 0, height: 0 };

          if(!obj)
             return r;

          else if(typeof obj == "string")
             obj = document.getElementById(obj);


          if(typeof obj != "object")
             return r;

          if(typeof obj.offsetTop != "undefined") {

             r.height = parseInt(obj.offsetHeight);
             r.width  = parseInt(obj.offsetWidth);
             r.left = r.top = 0;

             while(obj && obj.tagName != "BODY") {

                r.top  += parseInt(obj.offsetTop);
                r.left += parseInt(obj.offsetLeft);

                obj = obj.offsetParent;
             }
          }
          return r;
       }

if you want to subtract the padding / border-width is set in the css-file and not dynamic in the style attribute:

    var elem = document.getElementById(id);
    var borderWidth = 0;

          try {
             borderWidth = getComputedStyle(elem).getPropertyValue('border-top-width');

             } catch(e) {

             borderWidth = elem.currentStyle.borderWidth;
          } 
    borderWidth = parseInt(borderWidth.replace("px", ""), 10);

and with the padding the same. then you calculate it.

Mic
  • 523
  • 6
  • 18
  • 1
    in the internet you can find all sort of rubbish code. I want THE ULTIMATE answer for this mystery, not a bloated, slow code..but thanks for the answer :) – vsync Nov 17 '12 at 23:28
  • if you have a dynamic height without a css attribute "height" for an element the method with "getComputedStyle" won't work. Or i am wrong? – Mic Nov 17 '12 at 23:33
  • ok. i thought the code with "getComputedStyle..." just read out the css attributes and doesn't calculate it if no "height" exists. – Mic Nov 17 '12 at 23:39
  • 2
    so i try it in a fiddle and IE is special again: if there is no height you get the value auto: http://jsfiddle.net/Kxsvx/ – Mic Nov 17 '12 at 23:47
  • good detective work Mic! IE8 and below does show it's ugly face here. but there MUST be a more simple solution to this simple thing.. – vsync Nov 18 '12 at 02:46
  • well, you can get the padding and borders and subtract it from the clientHeight of the element I guess. – vsync Nov 18 '12 at 03:03
  • maybe IE8 is gone in some years :D but be sure about the differences bitween the values of innerHeight: http://stackoverflow.com/questions/833699/clientheight-clientwidth-returning-different-values-on-different-browsers i will edit this post to post a smaller code – Mic Nov 18 '12 at 10:27
  • This post is from like 3 years ago, and now i've checked and they are all the same – vsync Nov 18 '12 at 19:25
1

You can simply use the clientHeight and clientWidth properties.

MDN web doc for Element.clientHeight — clientWidth works exactly the same way.

Tilepaper
  • 78
  • 5
-1

i had the same problem and found out there is no native cross plattform solution but the solution is easy though

var actual_h = element.offsetHeight;

            if(parseInt(element.style.paddingTop.replace('px','')) > 0){
                actual_h=actual_h -  parseInt(element.style.paddingTop.replace('px',''));

            }
            if(parseInt(element.style.paddingBottom.replace('px','')) > 0){
                actual_h=actual_h -  parseInt(element.style.paddingBottom.replace('px',''));

            }
john Smith
  • 17,409
  • 11
  • 76
  • 117
  • 2
    Be advised that, as MDN [states](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/style#Getting_style_information), "The `style` property is not useful for learning about the element's style in general, since it represents only the CSS declarations set in the element's inline `style` attribute [...]". – Spooky Feb 25 '15 at 06:14