Home > OS >  Bottom aligned navigation stick to top on scroll
Bottom aligned navigation stick to top on scroll

Time:12-15

I have a fixed navigation that I've previously used to hide and reveal when you scroll up or down and when you reach the top of the page. See a working example here.

However I'm struggling to adjust it so that it works when the navigation is on the bottom of the page. I would like the navigation to sit below the hero then as the user scrolls it fixes the navigation to the top. Like this example here.

You can see in this JSFiddle when you scroll down the page the navigation jumps to the top. I want to it be able to work responsively and automatically know what the threshold should be as well as work in most browsers, including latest IE.

Code below:

(function () {

        var doc = document.documentElement;
        var w = window;

        var curScroll;
        var prevScroll = w.scrollY || doc.scrollTop;
        var curDirection = 0;
        var prevDirection = 0;

        var header = document.getElementById("top-wrapper");
        var toggled;
        var threshold = 200;

        var checkScroll = function () {
            curScroll = w.scrollY || doc.scrollTop;
            if (curScroll > prevScroll) {
                // scrolled down
                curDirection = 2;
            } else {
                //scrolled up
                curDirection = 1;
            }

            if (curDirection !== prevDirection) {
                toggled = toggleHeader();
            }

            prevScroll = curScroll;
            if (toggled) {
                prevDirection = curDirection;
            }
        };

        var toggleHeader = function () {
            toggled = true;

            if (curDirection === 2 && curScroll > threshold) {
                header.classList.add("hide");
                header.classList.add("fixed");
            } else {
                toggled = false;
            }

            if (curDirection === 1) {
                header.classList.remove("hide");
                if (curScroll < threshold) header.classList.remove("fixed");
            } else {
                toggled = false;
            }

            return toggled;
        };

        window.addEventListener("scroll", checkScroll);

    })();    
body {
  padding: 0;
  margin: 0;
}

main {
  min-height: 20000px;
}

#hero-banner{
  background:black;
  width:100%;
  height:90vh;
}

h1 {
  padding-top: 40px;
  margin:0;
  color:white;
  text-align:center;
}

#top-wrapper {
  width: 100%;
  height: 10vh;
  background: red;
  position: relative
  top: auto;
  bottom:0px;
  transition: all 0.3s ease;
}

#top-wrapper.hide {
  top: -50px;
}

#top-wrapper.fixed {
  background: blue;
  top:0;
  position:fixed;
}

ul {
  margin:0;
  padding:0;
  list-style:none;
  width:100%;
  text-align:center;
}

li {
  display:inline-block;
}
<main>
  <section id ="hero-banner">
    <h1>Im a heading in the hero</h1>
  </section>
  
  <section id="top-wrapper">
    <ul>
      <li><a href="#">Link 1</a></li>
      <li><a href="#">Link 2</a></li>
      <li><a href="#">Link 3</a></li>
      <li><a href="#">Link 4</a></li>
    </ul>
  </section>
</main>

CodePudding user response:

If I am understanding your problem correctly, you can just use sticky positioning:

#top-wrapper {
    position: sticky;
}

This makes it follow normal page progression until it reaches top of page, and then it is fixed. However, it does not work on certain old browsers, such as IE.

CodePudding user response:

You can achieve the same by using

#top-wrapper {
    position: sticky;
    top: 0;
}

As per checking your code, it seems it's related with the way you configure your function to apply the .fixed class. I'd look for a different approach, with more time I can check what could be better to change the navbar style

  • Related