简体   繁体   中英

Navigation bar jumping to the right when position fixed is added with js, trying to compensate with width(calc), but open side navigation breaks it

I am working on a small site, where I am trying to learn how different navigation menus can interact with each other with html, css and js. My issue is that my top navigation bar does not interact correctly with my sidebar navigation. When i add the sticky class to my top navigation bar with js (= scrolling) and sidenavigation is open (= margin left on sidenavigation is 350px) my top navigation jumps out of the page. Is there a way to compensate for this?

Here is my js for fixed top navigation menu when scrolling:

let sectionMain = document.getElementById("section-main");
let navbar = document.getElementById("navbar");
let navPos = navbar.getBoundingClientRect().top;

window.addEventListener("scroll", e => {
  let viewportHeight = window.innerHeight;
  let scrollPos = window.scrollY;
  if (scrollPos > navPos) {
    navbar.classList.add('sticky');
    sectionMain.classList.add('navbarOffsetMargin');
  } else {
    navbar.classList.remove('sticky');
    sectionMain.classList.remove('navbarOffsetMargin');
  }
});

window.addEventListener("scroll", e => {
  let viewportHeight = window.innerHeight;
  let scrollPos = window.scrollY;
  if (scrollPos > navPos) {
    sidenavid.classList.add('sticky');
  } else {
    sidenavid.classList.remove('sticky');
  }
});

CSS for top navigation:

#navbar.sticky {
    position: fixed;
    top: 0;
    box-shadow: 5px -1px 6px 5px #dad7d7;
    clip-path: inset(-5px -5px -200px -0px);
    background-color: #e3f4f1;
    transition: 0.5s;
    z-index: 1000;
}

As mentioned I also have a sidenavigation bar, that is opened/closed (width 0/350px) with a button:

function toggleNav() {
  var element = document.getElementById("sidenavid");
  if (element.style.width == "350px") {
    element.style.width = "0px";
  } else {
    element.style.width = "350px";
  }
  var element = document.getElementById("main");
  if (element.style.marginLeft == "350px") {
    element.style.marginLeft = "0px";
  } else {
    element.style.marginLeft = "350px";
  }

HTML:

<body>
    <header>
        <div id="sidenavid" class="sidenavclass">
            <a href="#" class="closeicon">
                <h1 class="h1-top" aria-hidden="true">h1 title</h1>
            </a>
            <a href="#">Menu</a>
            <a href="#">Menu</a>
            <a href="#">Menu</a>
            <a href="#">Menu</a>
        </div>
        <div id="main">
            <nav id="navbar">
                <span onclick="toggleNav()">
                    <div class="navbar-brand">
                        <i onclick="toggleIcon(this)" class="fa fa-bars fa-2x"></i>
                    </div>
                </span>
                <ul class="nav-list" id="navlist">
                    <li class="nav-list-items"><a href="#">Home</a></li>
                    <li class="nav-list-items dropdown"><a href="#">Products</a>
                        <div class="dropdown-content">
                            <a href="#">Product #1</a>
                            <a href="#">Product #2</a>
                        </div>
                    </li>
                    <li class="nav-list-items dropdown"><a href="#">Information</a>
                        <div class="dropdown-content">
                            <a href="#">Courses</a>
                            <a href="#">Tutorials</a>
                        </div>
                    </li>
                    <li class="nav-list-items"><a href="#">Contact</a></li>
                </ul>
            </nav>
            <section id="section-main">
                <div class="article-container">
                    <article class="section-container">
                        <h1>This is the title of the section</h1>
                        <p class="section-text">
                            Here is the main section text in a paragraph tag that is supposed to xyz
                        </p>
                    </article>
                </div>
            </section>
            <section id="section-main">
                <div class="article-container">
                    <article class="section-container">
                        <h1>This is the title of the section</h1>
                        <p class="section-text">
                            Here is the main section text in a paragraph tag that is supposed to xyz
                        </p>
                    </article>
                </div>
            </section>
        </div>
    </header>
    <script src="https://kit.fontawesome.com/9beebcdd4b.js" crossorigin="anonymous"></script>
    <script src="js/scripts.js"></script>
</body>

My top navigation bar does not seem to work with my side bar, as it is pushed out of the viewport when it is scrolling (class sticky is added) and side bar is open (width of sidenav 350px. I tried compensating by adding following if statement to my code, but it does not seem to work as intended.

  var element = document.getElementById("navbar");
  if (main.style.marginLeft == "350px" || navbar.classList.contains('sticky')) {
      element.style.width = "calc(100% - 350px)";
    } else {
      element.style.width = "100%";
    }

Here is full jsfiddle: https://jsfiddle.net/louvalman/xf8kwrv9/6/ (site only works in full screen so far) Thanks in advance to anyone willing to help out a newbie!

I think it is pretty funny you add a class called sticky but it sets the position value of the #navbar to fixed.

If you would set the position to sticky instead of fixed you would already almost get the result that you are after.

The only thing to change is then to add a space between the content of the navbar using justify-content: space-between. You can use this instead of the margin auto on the nav list class you've set.

#navbar {
    display: inline-flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    position: relative;
}

#navbar.sticky {
    position: sticky;
    top: 0;
    box-shadow: 5px -1px 6px 5px #dad7d7;
    clip-path: inset(-5px -5px -200px 0px);
    background-color: #e3f4f1;
    transition: 0.5s;
    z-index: 1000;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM