liveBook · Manning

offsetHeight

As explained in Secrets of the JavaScript Ninja, Second Edition

A DOM element property reporting its layout height in pixels, including padding and borders.

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

How Secrets of the JavaScript Ninja, Second Edition covers it

How deep it goes
Explains measured dimensions and a procedure for measuring hidden elements, but does not detail browser layout internals.
Examples
Demonstrates measuring a hidden image by temporarily changing its display, visibility, and position styles.
What it assumes
Assumes familiarity with DOM elements and style properties; does not teach those concepts from zero.
What you can do after
Apply DOM element properties to read a rendered height and temporarily measure an element hidden with display set to none.
How it connects
Ties element dimensions to CSS style properties, DOM layout, and layout thrashing.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Secrets of the JavaScript Ninja, Second Edition. The section links point to the parts of the book it draws on.