Skip to main content

A sticky(ish) navigation header which is animated off-screen while scrolling down, reappearing on scrolling up, maximising the vertical display space on smaller screens.

Scroll direction dependent header

Scroll down and the header navigation moves off-screen. Scroll up and it reappears.

version 2.0 21/02/2016.

HTML

Language HTML
<nav id=nav class=nav>
  // navigation header content
</nav>

CSS

Language CSS
.nav_clone {
  visibility: hidden;
}
.nav_fixed {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  z-index: 1;
  box-shadow: 0 2px 4px 0 rgba(0,0,0,.5);
  transition: transform 0.4s ease-out;
}

The navigation up & down position is controlled via a transform: translateY(…) inserted by script

JavaScript

Requires detect CSS transform3d browser support.

Language JavaScript
var StickyNav = (function () {
  "use strict";
  var id = "nav",
      originalObj = document.getElementById(id),
      lastScrollTop = -1,
      height,
      cloneObj,
      minDistance;
Language JavaScript
  var _cloneObj = function (obj) {
    var cloneObj = obj.cloneNode(true);
    cloneObj.id = obj.id + "_clone";
    cloneObj.classList.add(cloneObj.id);
    obj.parentNode.insertBefore(cloneObj, obj);
    return cloneObj;
  };
Language JavaScript
  var _setVars = function () {
    height = cloneObj.offsetHeight;
    minDistance = cloneObj.offsetTop + height;
  };
Language JavaScript
  var _redrawLoop = function () {
    var pageY = window.pageYOffset;
    if (lastScrollTop !== pageY) {
      var offset = window.scrollY,
          travelledMin = (minDistance - offset) <= 0,
          isDirectionUp = offset < lastScrollTop;
      if (travelledMin) {
        if (isDirectionUp) {
          originalObj.style.transform = "translateY(0)";
        } else {
          originalObj.style.transform = "translateY(" + -height + "px)";
        }
      }
      lastScrollTop = pageY;
    }
    requestAnimationFrame(_redrawLoop);
  };
Language JavaScript
  if (originalObj && hasTransform3d) {
    cloneObj = _cloneObj(originalObj);
    cloneObj.style.visibility = "hidden";
    originalObj.classList.add("nav_fixed");
    _setVars();
    _redrawLoop();
    window.addEventListener("resize", _setVars, false);
  }
}());

Google Closure Compiled

377 bytes gzipped (548 bytes uncompressed).

Language JavaScript
// Sticky header nav v2.0 21/02/2016
// 377 bytes gzipped (548 bytes uncompressed)
var StickyNav=function(){var d=document.getElementById("nav"),e=-1,f,c,g,l=function(b){var a=b.cloneNode(!0);a.id=b.id+"_clone";a.classList.add(a.id);b.parentNode.insertBefore(a,b);return a},h=function(){f=c.offsetHeight;g=c.offsetTop+f},k=function(){var b=window.pageYOffset;if(e!==b){var a=window.scrollY,c=a<e;0>=g-a&&(d.style.transform=c?"translateY(0)":"translateY("+-f+"px)");e=b}requestAnimationFrame(k)};d&&hasTransform3d&&(c=l(d),c.style.visibility="hidden",d.classList.add("nav_fixed"),h(),k(),window.addEventListener("resize",h,!1))}();

Socialise: