Late to the party but I'll give my take on this one anyway.
The following solution is written in Vanilla Javascript but the same logic applies to jQuery obviously.
Elements do not necessarily need to be visibile to be measured, they just need not to be display: none;
. Display:none means 0 height in the computed style, so we have to find a workaround.
We can sort of emulate a display:none
in two easy steps:
- we set
visibility:hidden
(so the element is not visible)
- we set
position:absolute
(so the element takes no space)
Then we'll set its display
to block
(or empty string, it doesn't matter as long as it's not none
).
We will then have an invisible div that will take no space in the document but will retain its own original dimensions. This way it will be fully accessible through JavaScript, even if no dimension was previosuly set in the css.
In a loop we'll run getComputedStyle
against each div we need, looking for its height.
// start loop
getComputedStyle(el).getPropertyValue('height');
// end loop
If you still need to have the display set to none at the end of the loop you can restore it.
The script is nothing complicated really, and runs without any flickering.
Here's a demo.
var par = document.getElementById('hiddenParent'),
cd = par.querySelectorAll('.childDiv'),
len,
heights = [],
i;
function getHeight(){
len = cd.length;
// 1.we hide the parent
par.style.visibility = 'hidden';
// 2. we set its position to absolute, so it does not
// take space inside the window
par.style.position = 'absolute';
// 3. we set its display to block so it will gain back its natural height
par.style.display = 'block';
// 4. we start looping over its children
while(len--){
// we get the height of each children... here we're just storing them in array,
// which we will alert later
heights[len] = window.getComputedStyle( cd[len] ).getPropertyValue('height');
}
// 5. Job is done, we can bring back everything to normal (if needed)
par.cssText = 'display: none';
}
document.getElementById('starter').addEventListener('click',function(){
getHeight();
alert(heights);
});
#hiddenParent, .another-div{
background: teal;
width: 40%;
padding: 20px;
text-align: center;
color: white;
font-family: Arial;
text-transform: uppercase;
color: #ccc;
}
.childDiv{
background: purple;
padding: 10px;
margin-bottom: 10px;
}
.another-div{
background: orange;
color: #1F9091;
}
<button id="starter"> Calculate heights </button>
<!-- hiddenParent is between two other divs but takes no space in the document as it's display:none -->
<div id="hiddenParent" style="display: none;">
<div class="childDiv">child div 1</div>
<div class="childDiv">child div 2</div>
<div class="childDiv">child div 3</div>
</div>
<div class="another-div">
here's another div
</div>