Search code examples
javascriptjqueryscreen-orientationorientation-changesouterheight

jQuery .outerHeight() on an element returns incorrect size on orientation change


I am trying to get the outerHeight of my top navigation bar on my website for some calculations and it works perfectly when loading/reloading the webpage. However, it returns the wrong height when I change the orientation of the screen in Chrome Developer Tools to landscape. My code listens for a resize change event before getting the outerHeight, so I'm not sure why it is returning the wrong height on orientation change of the webpage but the correct height when loading/reloading the webpage. I think it might have to do with the resize listener not waiting for the page to fully load after an orientation change but I am unsure.

For the code snippet, I tried adding Bootstrap 4.5 to it but it kept returning an error. If someone wanted to add that in who knows how to do that, that would be much appreciated so that page is more accurate when running the code snippet.

body {
  background-position: center center;
  background-size: auto;
  position: absolute;
  overflow-x: hidden;
  overflow-y: scroll;
  width: 100%;
  height: 100%;
  font-family: 'Montserrat', sans-serif;
  color: white;
}

a {
  color: white;
}

a:hover {
  text-decoration: none;
  color: white;
}

#content-wrapper {
  overflow-y: scroll;
  -ms-overflow-style: none;
  overflow: -moz-scrollbars-none;
}

#content-wrapper::-webkit-scrollbar {
  display: none;
}

#top_navbar {
  padding: 0;
}

.navbar-brand {
  padding: 0;
}

#navbar_logo {
  width: 15vw;
  margin-right: 6vw;
  margin-left: 0 !important;
}

.nav-link {
  font-family: Arial, Helvetica, sans-serif;
  font-size: 2vw;
  -webkit-text-fill-color: white;
  -webkit-text-stroke-width: 1px;
  -webkit-text-stroke-color: #1b1b1b;
  letter-spacing: 1px;
}

.nav-link:hover {
  -webkit-text-fill-color: #1b1b1b;
  -webkit-text-stroke-width: 1px;
  -webkit-text-stroke-color: white;
}

.nav-item {
  margin-left: 3vw;
  margin-right: 3vw;
}

#bottom_footer,
#legal_documents {
  background-color: #1b1b1b;
  width: 100%;
  position: absolute;
  display: table;
  bottom: 0;
  text-align: center;
  padding-top: 1%;
  padding-bottom: .4%;
}

#legal_documents {
  bottom: unset;
  font-size: 10px;
  padding-bottom: .6% !important;
}

#social_buttons::selection {
  color: none;
  background: none;
}

#social_buttons::-moz-selection {
  color: none;
  background: none;
}

#social_buttons a {
  display: inline-block;
  margin: 0 15px;
  background-position: center center;
  background-repeat: no-repeat;
  background-size: contain;
}

#bottom_footer a:hover,
#legal_documents a:hover {
  opacity: 0.5;
}
<html lang="en">
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, shrink-to-fit=no">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css" />
  <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.min.js"></script>
</head>
<body>
  <nav id="top_navbar" class="navbar navbar-expand-sm navbar-dark">
    <a class="navbar-brand" href="" title="Melo Relo">
      <img id="navbar_logo" src="">
    </a>
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbar_items" aria-controls="navbar_items" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
        </button>

    <div class="collapse navbar-collapse" id="navbar_items">
      <ul class="navbar-nav">
        <li class="nav-item">
          <a class="nav-link" href="">LABEL</a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="">LABEL</a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="">LABEL</a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="">LABEL</a>
        </li>
      </ul>
    </div>
  </nav>

  <main id="content-wrapper" class="container-fluid">
  </main>

  <div id="bottom_footer">
    <div id="social_buttons">
      <a href="" class="facebook" title="Facebook" target="_blank"></a>
      <a href="" class="twitter" title="Twitter" target="_blank"></a>
      <a href="" class="instagram" title="Instagram" target="_blank"></a>
      <a href="" class="snapchat" title="Snapchat" target="_blank"></a>
      <a href="" class="youtube" title="YouTube" target="_blank"></a>
    </div>
    <div id="legal_documents">
      <a href="" title="Privacy Policy" target="_blank">PRIVACY POLICY</a> |
      <a href="" title="Terms and Conditions" target="_blank">TERMS AND CONDITIONS</a>
    </div>
  </div>
</body>

</html>


Solution

  • I figured out the issue. The reason why jQuery height methods were returning the wrong height calculation when changing the screen orientation to landscape was that the top navbar makes certain changes and these changes were made after getting the top navbar height. These changes should have been made before getting the top navbar height. The changes that are made to the top navbar include the size and actual image of the #navbar-logo and setting the #content-wrapper's margin-top to 0. After swapping around the code and waiting for the image to load, the correct height was returning on each orientation change.

      if (window_width <= 575) {
        $("#navbar_logo").attr("src", "/static/images/title-logo-mobile.jpg");
      } else {
        $("#navbar_logo").attr("src", "/static/images/title-logo.jpg");
      }
    
      $("#navbar_logo").on("load", function() {
        if (window_width <= 575) {
          $("#navbar_logo").css({"width":"28vw", "margin-left":"0"});
          navbar_height = $("#top_navbar").outerHeight(true) + 10;
          $('#content-wrapper').css("margin-top", navbar_height);
        } else {
          $("#navbar_logo").css({"width":"15vw", "margin-left":"3vw"});
          navbar_height = $("#top_navbar").outerHeight(true);
          $('#content-wrapper').css("margin-top", 0);
        }
        container_height = window_height - navbar_height - footer_height;
        $("#content-wrapper").css("height", container_height);
      });