Detect Scrolling Direction (Up/Down)

Tracks scroll direction and distance using two configurable thresholds, updating data-scrolling-direction ("up" / "down") and data-scrolling-started ("true" / "false") on the body. Use CSS attribute selectors to hide the navbar on scroll-down, shrink it after the threshold, and reveal it again on scroll-up.

scrolldirectionnavigationdata-attributesjavascriptcss

Code

index.html
html
<body data-scrolling-started="false" data-scrolling-direction="up"></body>
styles.css
css
.nav {
  transition: transform 1s ease, padding 1s ease;
  transform: translateY(0%) rotate(0.001deg);
  padding: 2em 1em;
}

/* Shrink nav when scrolling started */
[data-scrolling-started="true"] .nav {
  padding: 1em 1em;
}

/* Move nav out of window when scrolling down */
[data-scrolling-started="true"][data-scrolling-direction="down"] .nav {
  transform: translateY(-100%) rotate(0.001deg);
}

/* Change background to filled when scrolling started */
.nav__inner {
  transition: background-color 1s ease;
  background-color: transparent;
}

[data-scrolling-started="true"] .nav__inner {
  background-color: #fff;
}
script.js
javascript
function initDetectScrollingDirection() {
  let lastScrollTop = 0;
  const threshold = 10;    // Minimal scroll distance to switch to up/down
  const thresholdTop = 50; // Minimal scroll distance from top of window to start

  window.addEventListener('scroll', () => {
    const nowScrollTop = window.scrollY;

    if (Math.abs(lastScrollTop - nowScrollTop) >= threshold) {
      // Update Scroll Direction
      const direction = nowScrollTop > lastScrollTop ? 'down' : 'up';
      document.querySelectorAll('[data-scrolling-direction]').forEach(el =>
        el.setAttribute('data-scrolling-direction', direction)
      );

      // Update Scroll Started
      const started = nowScrollTop > thresholdTop;
      document.querySelectorAll('[data-scrolling-started]').forEach(el =>
        el.setAttribute('data-scrolling-started', started ? 'true' : 'false')
      );

      lastScrollTop = nowScrollTop;
    }
  });
}

// Initialize Detect Scrolling Direction
document.addEventListener('DOMContentLoaded', () => {
  initDetectScrollingDirection();
});

Guide

Attributes

Add data-scrolling-started="false" and data-scrolling-direction="up" to the <body>. The script updates both attributes on every qualifying scroll event.

threshold

The minimum pixel distance the user must scroll since the last recorded position before the direction attribute updates. Default is 10px. Increase it to reduce sensitivity and prevent flickering on tiny scroll nudges.

thresholdTop

The minimum distance from the top of the page (in pixels) before data-scrolling-started switches to "true". Default is 50px. This prevents the nav from shrinking before the user has meaningfully scrolled.

Animating

Use CSS attribute selectors to respond to the changing values. For example: hide the nav with translateY(-100%) when [data-scrolling-started="true"][data-scrolling-direction="down"], shrink its padding when scrolling has started, and switch the background from transparent to filled.