When an element’s height is set to auto, its style height may not tell you its actual rendered size. Read offsetHeight for the element’s layout height in pixels, including padding and borders; it is useful when positioning one element relative to another. section 12.3.5
There’s a catch: an element with display set to none has no layout dimensions, so offsetHeight returns 0. To measure it without showing it, temporarily set display to block, visibility to hidden, and position to absolute; read the dimension, then restore the original styles. section 12.3.5
Listing 12.9. Grabbing the dimensions of hidden elements
<div>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Suspendisse congue facilisis dignissim. Fusce sodales,
odio commodo accumsan commodo, lacus odio aliquet purus,
<img src="../images/ninja-with-pole.png" id="withPole" alt="ninja pole"/>
<img src="../images/ninja-with-shuriken.png"
id="withShuriken" style="display:none" alt="ninja shuriken" />
vel rhoncus elit sem quis libero. Cum sociis natoque
penatibus et magnis dis parturient montes, nascetur
ridiculus mus. In hac habitasse platea dictumst. Donec
adipiscing urna ut nibh vestibulum vitae mattis leo
rutrum. Etiam a lectus ut nunc mattis laoreet at
placerat nulla. Aenean tincidunt lorem eu dolor commodo
ornare.
</div>
<script
(function(){ #A
const PROPERTIES = { #B
position: "absolute",
visibility: "hidden",
display: "block"
};
window.getDimensions = element => { #C
const previous = {}; #D
for (let key in PROPERTIES) {
previous[key] = element.style[key];
element.style[key] = PROPERTIES[key]; #E
}
const result = { #F
width: element.offsetWidth,
height: element.offsetHeight
};
for (let in PROPERTIES) { #G
element.style[key] = previous[key];
}
return result;
};
})();
document.addEventListener("DOMContentLoaded", () => {
setTimeout(() => {
const withPole = document.getElementById('withPole'),
withShuriken = document.getElementById('withShuriken');
assert(withPole.offsetWidth === 41,
"Pole image width fetched; actual: " +
withPole.offsetWidth + ", expected: 41"); #H
assert(withPole.offsetHeight === 48,
"Pole image height fetched: actual: " +
withPole.offsetHeight + ", expected 48");
assert(withShuriken.offsetWidth === 36, #I
"Shuriken image width fetched; actual: " +
withShuriken.offsetWidth + ", expected: 36");
assert(withShuriken.offsetHeight === 48,
"Shuriken image height fetched: actual: " +
withShuriken.offsetHeight + ", expected 48");
const dimensions = getDimensions(withShuriken); #J
assert(dimensions.width === 36, #K
"Shuriken image width fetched; actual: " +
dimensions.width + ", expected: 36");
assert(dimensions.height === 48,
"Shuriken image height fetched: actual: " +
dimensions.height + ", expected 48");
},3000);
});
</script>
See a utility that saves an element’s inline styles, temporarily changes them to measure a hidden element, and restores them afterward. section 12.3.5
Batch DOM updates where possible: alternating reads and writes can force repeated layout recalculations and make an application less responsive. section 12.5
