A sticky Menu at the Bottom of your page

_config.yml

I saw something that Basecamp had done really well which I liked. A toolbar that sticks to the bottom of your window until you scroll past it. In my particular case, I’m using it to put in my pagination links there. Everything is hard-coded, but you may change it around to suit yourself. It’s a small feature that makes your site that much more “nice” and it makes things easier for your users.

I’m using Stimulus JS for this. Here is a nice introduction for you.

import { Controller } from "stimulus";

export default class extends Controller {

  connect(){          
   this.onScrollRunning = false      
   this.elementYPoint = this.element.getBoundingClientRect().bottom + window.pageYOffset;
  }    

  onScroll(event) {    
    if (!this.onScrollRunning) {      
      this.onScrollRunning = true;
      if (window.requestAnimationFrame) {        
        window.requestAnimationFrame(this.scroll.bind(this));
      } else {         
         setTimeout(this.scroll.bind(this), 66);
      }
     }
  }

  scroll() {
    let windowBottomPosition = window.scrollY + window.innerHeight    
    
    // console.log(`window bottom position: ${window.scrollY + window.innerHeight}`)
    // console.log(`element y point: ${this.elementYPoint}`)

    if (windowBottomPosition >= this.elementYPoint) {
      if (! this.element.classList.contains("position-relative")) {        
        this.element.classList.add("position-relative")
      }

      if (this.element.classList.contains("fixed-bottom")) {        
        this.element.classList.remove("fixed-bottom")
      }

    } else  
    { 
      if (! this.element.classList.contains("fixed-bottom")) {        
        this.element.classList.add("fixed-bottom")
      }

      if (this.element.classList.contains("position-relative")) {        
        this.element.classList.remove("position-relative")
      }
    }
    this.onScrollRunning = false
  }
}

And here is the HTML used:

  <div data-controller="fixed-bottom" data-action="scroll@window->fixed-bottom#onScroll"> 
    <div class="row align-items-center justify-content-center">
      <%== pagy_bootstrap_nav(@pagy) %>
    </div>
  </div>

Sources

Inspired by this blog post: Stimulus.js Tutorial: Listening to onScroll Events for a Sticky Table Header by John

Written on September 15, 2020