Search code examples
htmlcssscrollbarhorizontal-scrolling

Horizontal scrollbar stick to bottom


I am looking for a solution for a sticky-bottom horizontal scrollbar. On view, there is a huge table and I didn't want to give fixed height to that so we'll have page level vertical scrollbar but I have given fixed width so there will be a grid-level horizontal scrollbar.

The problem is I don't want to go all the way down below to use the horizontal scrollbar, I am looking for a solution to make the horizontal scrollbar stick to the bottom of the view.

enter image description here


Solution

  • I find out a workaround using a custom scroll bar. checkout here, https://codepen.io/devashishg/pen/oNzREaw

    const $scroller = document.getElementById("scroller");
    const $containers = document.getElementById("container_body");
    const $wrapper = document.getElementById("wrapper");
    let ignoreScrollEvent = false;
    animation = null;
    const scrollbarPositioner = () => {
      const scrollTop = document.scrollingElement.scrollTop;
      const wrapperTop = $wrapper.offsetTop;
      const wrapperBottom = wrapperTop + $wrapper.offsetHeight;
    
      const topMatch = window.innerHeight + scrollTop >= wrapperTop;
      const bottomMatch = scrollTop <= wrapperBottom;
    
      if (topMatch && bottomMatch) {
        const inside =
          wrapperBottom >= scrollTop &&
          window.innerHeight + scrollTop <= wrapperBottom;
    
        if (inside) {
          $scroller.style.bottom = "0px";
        } else {
          const offset = scrollTop + window.innerHeight - wrapperBottom;
    
          $scroller.style.bottom = offset + "px";
        }
        $scroller.classList.add("visible");
      } else {
        $scroller.classList.remove("visible");
      }
    
      requestAnimationFrame(scrollbarPositioner);
    };
    requestAnimationFrame(scrollbarPositioner);
    $scroller.addEventListener("scroll", (e) => {
      if (ignoreScrollEvent) return false;
      if (animation) cancelAnimationFrame(animation);
      animation = requestAnimationFrame(() => {
        ignoreScrollEvent = true;
        $containers.scrollLeft = $scroller.scrollLeft;
        ignoreScrollEvent = false;
      });
    });
    $containers.addEventListener("scroll", (e) => {
      if (ignoreScrollEvent) return false;
      if (animation) cancelAnimationFrame(animation);
      animation = requestAnimationFrame(() => {
        ignoreScrollEvent = true;
        $scroller.scrollLeft = $containers.scrollLeft;
        ignoreScrollEvent = false;
      });
    });
    .long {
      width: 1550px;
    }
    
    #container_body {
      overflow: hidden;
      padding-bottom: 20px;
    }
    
    #scroller {
      position: fixed;
      left: 0;
      right: 0;
      bottom: 0;
      overflow-x: scroll;
      display: none;
    }
    
    #scroller.visible {
      display: block;
    }
    
    #scroller .long {
      height: 1px;
    }
    Hello<br/>
    <div id="wrapper">
        <div id="container_body">
          <div class="long"> Long text</div>
          Long text
          <br />Long text
          <br />Long text
          <br />Long text
          <br />Long text
          <br />Long text
          <br />Long text
          <br />Long text
          <br />Long text
          <br />Long text
          <br />Long text
          <br />Long text
          <br />Long text
          <br />Long text
          <br />Long text
          <br />Long text
          <br />Long text
          <br />Long text
          <br />Long text
          <br />Long text
          <br />Long text
          <br />A. Long text
          <br />
        </div>
        <div id="scroller">
          <div class="long">
          </div>
        </div>
    </div>
    Bye

    please share any alternate solution if you have one.