user1406440
user1406440

Reputation: 1655

Reveal nav when scrolling down

What I'm trying to achieve is when a page is scrolled down the navigation is hidden - as in it disappears off the top of the screen like it traditionally would. When a user scrolls back up the page, the navigation slides into view again. Likewise, if you scroll down again, it's hidden.

I've tried a few different plugins for this and they nearly work. The one I'm currently looking at is "jquery-unveiled-navigation"

Link: https://github.com/weaintplastic/jquery-unveiled-navigation Example: http://codepen.io/weaintplastic/full/RNpXOO/

This very nearly does what I want it to. It could do with some classes once the script is 'active'. As I only want to add a background-color when the script is 'active'. So it would be transparent until the navigation had left the screen and wasn't at the top.

Also, I know with this navigation if you scroll back up so half the navigation is in view, it will quickly adjust so you can see the bar in it's entirety. But I quite like the idea of it only showing as much as you've scrolled up by. So if the nav is 100px tall, and you scroll 30px, you only see the bottom 30px of the bar. Scrolling back down would hide the bar again, pixel by pixel - does that make sense?

So the steps would be (if this makes it clearer):

  1. Header at the top of the page, transparent background.
  2. When scrolling down, pixel by pixel the navigation leaves the screen.
  3. When the user scrolls back up, the header starts to reveal it's self again - this time is has a background-color.
  4. Once header hits the top of the browser again, the background is removed.

My markup is pretty simple. The bar only holds a logo and navigation toggle as the nav is hidden until the toggle is clicked, which displays the nav full screen.

<header class="page-head">

    <a href="#" class="page-head__home-link"></a>

    <a href="#" class="page-head__toggle"><span>Menu</span></a>

    <nav class="site-nav">
        <ul class="site-nav__list">
            <li class="site-nav__item"><a href="#" class="site-nav__link">Link</a></li>
            <li class="site-nav__item"><a href="#" class="site-nav__link">Link</a></li>
            <li class="site-nav__item"><a href="#" class="site-nav__link">Link</a></li>
            <li class="site-nav__item"><a href="#" class="site-nav__link">Link</a></li>
            <li class="site-nav__item"><a href="#" class="site-nav__link">Link</a></li>
        </ul>
    </nav>

</header>

I've removed the SVG I have within page-head__home-link otherwise it would be a wall of code!

Hope someone can help :)

Upvotes: 1

Views: 485

Answers (1)

Chris Moody
Chris Moody

Reputation: 140

You can do this pretty easily without jquery or a library. You just need to watch the scroll event and when the direction changes place the header just above the field of vision and then as you continue to scroll make sure it never moves off of the top of the parent container.

var body, direction, margin, pageHead, pageHeadHeight, scrolled;

body = document.getElementById('tall');
scrolled = 0;
direction = null;
pageHead = document.getElementsByClassName('page-head')[0];
pageHeadHeight = pageHead.offsetHeight - 1;
margin = 0;

body.addEventListener("scroll", function(event) {
  if (scrolled < body.scrollTop) {
    direction = 'down';
  } else {
    if (direction === 'down') {
      direction = 'up';
      margin = Math.max(0, body.scrollTop - pageHeadHeight);
    }
    if (margin > body.scrollTop) {
      margin = body.scrollTop;
    }
    pageHead.style['margin-top'] = margin + 'px';
  }
  return scrolled = body.scrollTop;
});
.tall {
  background-color: blue;
  min-height: 3000px;
  min-width: 100%;
}
#tall {
  max-height: 180px;
  border: 3px solid pink;
  overflow: auto;
}
.page-head{
  color: white;
  display: inline-block;
}
a {
  color: white;
}
<div id="tall">
  <div class='tall'>
    <header class="page-head">

        <a href="#" class="page-head__home-link"></a>

        <a href="#" class="page-head__toggle"><span>Menu</span></a>

        <nav class="site-nav">
            <ul class="site-nav__list">
                <li class="site-nav__item"><a href="#" class="site-nav__link">Link</a></li>
                <li class="site-nav__item"><a href="#" class="site-nav__link">Link</a></li>
                <li class="site-nav__item"><a href="#" class="site-nav__link">Link</a></li>
                <li class="site-nav__item"><a href="#" class="site-nav__link">Link</a></li>
                <li class="site-nav__item"><a href="#" class="site-nav__link">Link</a></li>
            </ul>
        </nav>

    </header>
  </div>
</div>

Upvotes: 1

Related Questions