It’s about sticky navigation bar most modern web pages bother to have. Here’s the demo.

First thing first, we have to determine the distance of navigation bar relative to its parent (html tag). After that, stick the navigation bar at the point where the top edge of the current viewport (an area to display the web content in the browser) touches or passes through the top of navigation bar. In other words, the gap between the top edge of the page and navigation bar has been passed through (hidden because we scroll down the scroll bar).

  var nav = document.getElementById('main');
  var gapHeightBettweenParentAndNav = nav.offsetTop;

  function fixNav() {
    if (window.scrollY >= gapHeightBettweenParentAndNav) {
      // Stick the damn navigation.
      nav.classList.add('nav--fixed');

      // And so on...
    }
  }

  window.addEventListener('scroll', fixNav);

The only thing left is adding approriate CSS to style the sticky bar. Here’s how I do that.

  .nav--fixed {
    position: fixed;
    box-shadow: 0 5px rgba(0, 0, 0, 0.1);
  }

Here’s the markup.

  <nav id="main">
    <ul>
      <li class="logo"><a href="#">LOST.</a></li>
      <li><a href="#">Home</a></li>
      <li><a href="#">About</a></li>
      <li><a href="#">Images</a></li>
      <li><a href="#">Locations</a></li>
      <li><a href="#">Maps</a></li>
    </ul>
  </nav>

It’s very common to see a logo slide in after the top edge of the current viewport touched or passed through the navigation bar. How about adding more useless feature to our existing code?

  (function (window, undefined) {
    var nav = document.getElementById('main');
    var gapHeightBettweenParentAndNav = nav.offsetTop;
    var logo = document.querySelector('.logo');
    var siteWrap = document.querySelector('.site-wrap');

    function fixNav() {
      if (window.scrollY >= gapHeightBettweenParentAndNav) {
        nav.classList.add('nav--fixed');
        logo.classList.add('logo--shown');
        siteWrap.classList.add('site-wrap--bigger');

        // Fill the area the navigation bar left after its potition
        // being fixed relative to the `viewport`.
        document.body.style.paddingTop = `${nav.offsetHeight}px`;
      } else {
        nav.classList.remove('nav--fixed');
        logo.classList.remove('logo--shown');
        siteWrap.classList.remove('site-wrap--bigger');
        document.body.style.paddingTop = 0;
      }
    }

    window.addEventListener('scroll', fixNav);
  })(window)

Be careful! Once you decide to fix the block-level element’s position relative to the viewport, the area that element previously took up before being fixed will vanish. We have to add padding to its parent element, so the place where the navigation bar left would be filled appropriately.

That’s it for today. I think I kind of miss メリー メディオーアティ.