Search code examples
javascriptscrollscrollbarscroll-snap

How to set scrollLeft in JS while scroll snapping is enabled?


This jsFiddle shows the issue.

I am trying to allow horizontal scroll snapping using scroll-snap-type so that when the user scrolls, the scroll snaps to the nearest div.

I also want to scroll the div when the user presses a button. However, this doesn't seem to work when scroll-snap-type is applied to the container.

As shown in the jsFiddle, removing scroll-snap-type makes the button work. Keeping it, makes the button do nothing when clicked.

    function myFunction() {
  const element = document.getElementById("myDIV");
  element.scrollLeft = element.scrollLeft + 50;
}

document.getElementById("button").addEventListener('click', function(){

    myFunction();

})

CSS

.x.mandatory-scroll-snapping {
  scroll-snap-type: x mandatory;
}

HTML

  <button id="button"> CLICK</button>
  <div class="container x mandatory-scroll-snapping" id="myDIV">
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>
    <div>5</div>
  </div>

Solution

  • You are not increasing the scroll position enough to snap to the next <div>

    function myFunction() {
      const element = document.getElementById("myDIV");
      element.scrollLeft = element.scrollLeft + 400;
    }
    document.getElementById("button").addEventListener('click', function() {
      myFunction();
    })
    .holster{
      height:100%;
      display:flex;
      align-items:center;
      justify-content:space-between;
      flex-flow:column nowrap;
      font-family:monospace
    }
    .container{
      display:flex;
      overflow:auto;
      outline:lightgray dashed 1px;
      flex:none
    }
    .container.x{
      width:100%;
      height:128px;
      flex-flow:row nowrap
    }
    .container.y{
      width:256px;
      height:256px;
      flex-flow:column nowrap
    }
    .x.mandatory-scroll-snapping{
      scroll-snap-type:x mandatory
    }
    .container>div{
      text-align:center;
      scroll-snap-align:center;
      flex:none
    }
    .x.container>div{
      line-height:128px;
      font-size:64px;
      width:100%;
      height:128px
    }
    .container>div:nth-child(2n){
      background-color:#87ea87
    }
    .container>div:nth-child(odd){
      background-color:#87ccea
    }
    <button id="button"> CLICK</button>
    <div class="container x mandatory-scroll-snapping" id="myDIV">
      <div>1</div>
      <div>2</div>
      <div>3</div>
      <div>4</div>
      <div>5</div>
    </div>