title: $(document).ready malfunction, $(document).resize works - same handler
body: <p>I am trying to implement a dynamic hero with bootstrap and jQuery. The hero is a banner with a quote and a background image. The issue I am running into is when the quotes exceed a certain length, the text disappears as the total height of the children elements exceeds that of the container div. I have used jQuery to attach a document.ready and document.resize handler, which calculates the height of all the children and resizes the container div appropriately:</p>
  
  <pre><code>function getHeights() {
      let childVertOffset = $("#client-hero-child").offset().top;
      let childHeightTotal = 0;
  
      let children = $("[id=client-hero-child]");
      children.each(function () {
          childHeightTotal += ($(this).outerHeight());
      });
  
      return childHeightTotal + childVertOffset;
  }
  
  
  function fixContainerHeight(newHeight) {
      $("#client-hero").height(newHeight)
  }
  </code></pre>
  
  <p>I attach document.ready and resize handlers to the page as follows:</p>
  
  <pre><code>$(window).resize(function () {
      if (window.location.pathname.includes('clients/')) {
          fixContainerHeight(getHeights())
      }
  });
  
  
  $(document).ready(function () {
      if (window.location.pathname.includes('clients/')) {
          fixContainerHeight(getHeights())
      }
  });
  </code></pre>
  
  <p>The document.resize handler works perfectly, but the issue I'm having is that the document.ready handler seems to be firing before all the content has loaded correctly. The resizing is always off by a consistent amount (calculating the height of the children about 80px less than the resize handler does). What is more interesting is that when I duplicate the document.ready statement, the code works correctly (hints that the function fires too soon), but if I add the document.ready function to a setTimeout function, it doesn't work, which indicates the contrary. </p>
  
  <p>It works if I do the following and duplicate the handler (maybe an issue with the function firing before the content has loaded?):</p>
  
  <pre><code>$(document).ready(function () {
      if (window.location.pathname.includes('clients/')) {
          fixContainerHeight(getHeights())
      }
  });
  
  
  $(document).ready(function () {
      if (window.location.pathname.includes('clients/')) {
          fixContainerHeight(getHeights())
      }
  });
  
  </code></pre>
  
  <p>But this doesn't work:</p>
  
  <pre><code>setTimeout(function(){
      fixContainerHeight(getHeights())
  },100);
  </code></pre>
  
  <p>The html (erb) is as follows:</p>
  
  <pre><code>  &lt;div class="row" id="client-hero-child"&gt;
      &lt;div class="col-12 px-sm-0"&gt;
        &lt;%= image_tag(@case.logo.url, class: "float-left testimonial-logo") %&gt;
      &lt;/div&gt;
      &lt;div class="category-description"&gt;
        &lt;p class="left-align client-text"&gt;&lt;%= @case.category %&gt;&lt;/p&gt;
      &lt;/div&gt;
      &lt;p class="client-text"&gt;"&lt;%= @case.quote.html_safe %&gt;"&lt;/p&gt;
      &lt;div class="col-12 pt-3" id ="client-hero-child"&gt;
        &lt;span class="float-right client-text"&gt;&lt;%= @case.quotee %&gt;&lt;/span&gt;&lt;br/&gt;
        &lt;span class="float-right quote-position" style="margin-bottom: 15px"&gt;&lt;%= @case.quotee_position %&gt;&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  </code></pre>
  
  <p>Any help would be very much appreciated, thanks!</p>
  
  <p>Update: </p>
  
  <p>After some troubleshooting and console logging, I figured out that the issue is related to a CSS feature - I have the following css:</p>
  
  <pre><code>#client-hero {
    height: 520px;
    background-repeat: no-repeat;
    .banner_detail_height {
      position: relative;
      top: 20%;
    }
  </code></pre>
  
  <p>The 'top' property is causing the trouble, this seems to occur a split second after the page loads. This explains why the duplicated code fixes the issue. The first time the load handler runs, it calculates the vert offset as 110px, then the css is run, adding a 20% top margin, then the handler runs a 2nd time, and calculates a vert offset of 200px. </p>
  
  <p>Is there a way to ensure the styling is run prior to the handler?</p>