skip to Main Content

I created a navbar with a submenu. The navbar has an image as a logo. Used Javascript to create sticky. The problem is, when I open the submenu and when sticky is active, the logo(image) is glitching. I’m not facing this problem if the logo is pure text. I tried for hours to figure out the problem. Wrapped the entire navbar in multiple combinations of divs but couldn’t solve the issue. Further, the glitch occurs at random times- which is freaking me out more. I’m attaching part of my code here. Can anyone tell me what is causing the error

  function isInViewport(element) {
    const rect = element.getBoundingClientRect();
    return (
      rect.top >= 0 &&
      rect.left >= 0 &&
      rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
      rect.right <= (window.innerWidth || document.documentElement.clientWidth)
    );
  }

var navbar = document.getElementById("navbar");
var sticky = navbar.offsetTop;
var scrollHeight = document.body.scrollHeight;

function scrollDetect() {
  var lastScroll = 0;
  window.onscroll = function() {
    let currentScroll = document.documentElement.scrollTop || document.body.scrollTop; // Get Current Scroll Value

    if (currentScroll > 0 && lastScroll <= currentScroll) {
      lastScroll = currentScroll;
      navbar.classList.remove("sticky");
      navbar.classList.remove("z-index-999999");
    } else {
      lastScroll = currentScroll;
      navbar.classList.add("sticky");
      navbar.classList.add("z-index-999999");
    }

    if (currentScroll < 100) {
      navbar.classList.remove("sticky");
      navbar.classList.remove("z-index-999999");
    }

  };
}

scrollDetect();
.main-navbar {
  position: absolute;
  display: inline-flex;
  background-color: red;
  top: 3.7rem;
  width: 100%;
  height: 4.5rem;
}


/*Code for Sticky*/

.sticky {
  position: fixed;
  top: 0;
  width: 100%;
  transition: 0.3s height ease-in-out;
  -webkit-transition: 0.3s height ease-in-out;
  -moz-transition: 0.3s height ease-in-out;
  -ms-transition: 0.3s ease-in-out;
  -o-transition: 0.3s ease-in-out;
  animation: faceInEffect 0.3s;
  -webkit-animation: faceInEffect 0.3s;
}

.logo img {
  position: relative;
  margin-right: 11.1rem;
  left: 9%;
  margin-top: -3px;
  width: 330px;
}

.nav-list {
  font-size: 1rem;
  display: flex;
  width: 30%;
  margin-top: .7rem;
  margin-left: 2.7rem;
}

.nav-list li {
  position: relative;
}

.nav-list>li>a {
  color: black;
  display: block;
  font-size: 1.05rem;
  font-weight: 500;
  padding: 1.3rem 1rem;
}

.sub-menu {
  display: flex;
  position: absolute;
  box-sizing: border-box;
  background-color: white;
  visibility: hidden;
  top: 3.8rem;
  left: -34.4rem;
  width: 89.89rem;
  height: 35rem;
  z-index: 100;
  border-bottom-left-radius: 7px;
  border-bottom-right-radius: 7px;
}

.sub-menu a {
  position: relative;
  top: 2rem;
  color: black;
  font-size: 1.1rem;
  font-weight: 200;
  padding: 3rem 40px 0 40px;
}

.nav-list>li:hover .sub-menu {
    visibility: visible;
}

.z-index-999999{
z-index: 999999999;
}

.content {
 position: absolute;
 top: 100rem;
}
<div class="main-navbar" id="navbar">
  <div class="logo">
    <a><img src="https://static.nike.com/a/images/q_auto:eco/t_product_v1/f_auto/dpr_2.0/w_441,c_limit/9d1635ed-eed0-45b0-b34d-e00468e2f79e/tanjun-easyon-shoes-mplG1H.png" alt=""></a>
  </div>
  <nav>
    <ul class="nav-list">
      <li class="dropdown-item-1">
        <a href="">Men</a>
        <ul class="sub-menu">
          <li><a href="#">shirts</a> </li>
          <ul>
      </li>
      <ul>
  </nav>
</div>
<div class=content>
  content for scroll
</div>

2

Answers


    • If you asking something like this then it could be done something like this without a lot hassle like getBoundingClientRect or scrollDetect
    let prevScrollPos = window.pageYOffset;
    let visible = true;
    
    document.addEventListener("DOMContentLoaded", function() {
      const navbar = document.querySelector(".navbar");
    
      window.addEventListener("scroll", () => {
        const currentScrollPos = window.pageYOffset;
    
        if (currentScrollPos > prevScrollPos) {
    
          if (visible) {
            navbar.classList.remove("visible");
            navbar.classList.add("hidden");
            visible = false;
          }
        } else {
          if (!visible || currentScrollPos === 0) {
            navbar.classList.remove("hidden");
            navbar.classList.add("visible");
            visible = true;
          }
        }
    
        prevScrollPos = currentScrollPos;
      });
      if (window.pageYOffset === 0) {
        navbar.classList.remove("hidden");
        navbar.classList.add("visible");
        visible = true;
      }
    });
    *,
    *:before,
    *:after {
      box-sizing: border-box;
    }
    
    .navbar {
      background-color: #000;
      color: #fff;
      padding: 10px 0;
      position: sticky;
      top: 0;
      z-index: 100;
      padding-inline: 20px;
      border-radius: 10px;
      display: flex;
      align-items: center;
      justify-content: space-between;
      transition: opacity 0.3s ease-in-out, transform 0.3s ease-in-out;
    }
    
    .navbar a {
      color: #fff;
      text-decoration: none;
      padding: 10px 20px;
    }
    
    .navbar .logo {
      width: 50px;
      border-radius: 50%;
    }
    
    .navbar ul {
      display: inline;
    }
    
    .navbar.hidden {
      opacity: 0;
      transform: translateY(-100%);
    }
    
    .navbar.visible {
      opacity: 1;
      transform: translateY(0);
    }
    
    .content {
      padding: 20px;
    }
    
    p {
      padding-top: 10rem;
      padding-bottom: 10rem;
    }
    <body>
      <div class="navbar">
        <div class="logo">
          <img src="https://picsum.photos/200" alt="Logo" class="logo">
        </div>
        <ul>
          <a href="#home">Home</a>
          <a href="#about">About</a>
        </ul>
      </div>
    
      <div class="content">
        <section id="home">
          <h1>Welcome to Our Website</h1>
          <p>This is the home section of our website. Scroll down to see more content.</p>
          <p>This is the home section of our website. Scroll down to see more content.</p>
          <p>This is the home section of our website. Scroll down to see more content.</p>
          <p>This is the home section of our website. Scroll down to see more content.</p>
          <p>This is the home section of our website. Scroll down to see more content.</p>
        </section>
      </div>
    
      <script src="script.js"></script>
    </body>
    Login or Signup to reply.
  1. To fix this issue, you can make the logo’s positioning consistent by using position: absolute for both the regular and sticky states of the logo. Here’s a modified version of your CSS and HTML:

    .logo {
      position: absolute;
      left: 9%;
      top: 3px;
    }
    
    .sticky .logo {
      top: 10px; /* Adjust the top value as needed */
    }
    <div class="main-navbar" id="navbar">
      <div class="logo">
        <a><img src="https://static.nike.com/a/images/q_auto:eco/t_product_v1/f_auto/dpr_2.0/w_441,c_limit/9d1635ed-eed0-45b0-b34d-e00468e2f79e/tanjun-easyon-shoes-mplG1H.png" alt=""></a>
      </div>
      <nav>
        <ul class="nav-list">
          <!-- menu -->
        </ul>
      </nav>
    </div>

    By using position: absolute for both states of the logo, you ensure that its positioning remains consistent when the navbar becomes sticky. You may need to adjust the top value in the .sticky .logo selector to fine-tune the logo’s position when the navbar is sticky.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search