Getting the height of an element before added to the DOM

26,118

Solution 1

Elements don't have a height, in any real sense, until they've been added to the DOM, as their styles cannot be evaluated until then.

You can get around this easily enough using visibility: hidden so that the element can be added to the DOM (and its height determined) without causing visible flickering.

function test(a) {
  var a = document.createElement(a);
  a.style.visibility = 'hidden';
  document.body.appendChild(a);
  a.appendChild(document.createTextNode('Hello'));
  a.style.fontStyle = 'italic';
  a.style.top=(window.innerHeight/2 - a.clientHeight/2) + 'px';
  a.style.visibility = '';
  return a;
}

test('p').style.background = '#0f0';
p { position: absolute; top: 0; left: 0; }

(This is working on the assumption that you're using top because the element is absolutely positioned or fixed. If it weren't, you'd need to make it so temporarily.) Hidden elements still take up space in the DOM (so their sizes must be calculated), but cannot actually be seen by the user.

Solution 2

Here is a working demo of how to measure an element by briefly adding it to the DOM and inspecting its height, then removing it. This method might be costly since the node is cloned, so the added styles won't affect it afterwards and all DOM events will be removed from it.

If the inspected node has a lot of sub-nodes, this might not be efficient, but stil can be quite handy.

function getNodeHeight(node) {
    var height, clone = node.cloneNode(true)
    // hide the meassured (cloned) element
    clone.style.cssText = "position:fixed; top:-9999px; opacity:0;"
    // add the clone to the DOM 
    document.body.appendChild(clone)
    // meassure it
    height = clone.clientHeight
    // cleaup 
    clone.parentNode.removeChild(clone)
    return height
}


var newDiv = document.createElement("div");
newDiv.innerHTML = `Lorem ipsum dolor sit amet, consectetur adipiscing elit, 
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 

<h1>deserunt mollit anim id est laborum.<h1>`


// print the height of "newDiv"
console.log( getNodeHeight(newDiv) )

Share:
26,118
Ruffy
Author by

Ruffy

Updated on December 30, 2021

Comments

  • Ruffy
    Ruffy over 2 years

    Is there any way to get an element's height prior to appending it to the DOM? I know that clientHeight doesn't work as I've tried and it always returns 0. Are there other methods that may return the height or does the element have to be a part of the DOM in order for the height to be calculated?

    This is a sample of what I'm going for:

    function test(a) {
        var a=document.createElement(a)
        a.style.top=(window.innerHeight/2-a.clientHeight/2)+'px' //fixed position in CSS
        document.body.appendChild(a)
        }
    

    *Note: This is only a simplified version of the function I'm working on in order to project what I'm trying to achieve without all of the unneeded mess.

  • Ruffy
    Ruffy almost 13 years
    Flickering isn't the problem because it's practically instant. Edit: This does work! I thought that changing properties of elements as variables after appending them would have no affect, but evidently it does, and that's as good as a solution as I was looking for.
  • Ben Blank
    Ben Blank almost 13 years
    @Jimmy — I'm not sure what you mean. a can still be manipulated normally after adding it to the DOM. Any changes which might affect the height should be placed between the appendChild and a.top lines, but other than that, everything should work as expected.
  • Ruffy
    Ruffy almost 13 years
    I realized that I made an error in my function the first time trying it (the actual function has numerous elements within eachother). It worked when I added it after being placed at the very end, which is pretty much the solution I'm looking for even if in a bit of a different order.
  • Aswin
    Aswin almost 4 years
    using getBoundingClientRect after mounting will give the height and width or not irrespective of the position of the element?