0

Let's imagine an example of some content that dynamically inserted upon data fetch from server. The purpose is to display it like a bunch of items in a scroll-snapped container.

The problem is browser somehow randomly tries to scroll to some element but I want the container to stay at the first element no matter how many elements are inserted. The only exception is user that manually scrolls the container.

It works fine unless I add scroll-snap property.

Here is the code snippet

const startingIdx = 3;
  const batchSize = 10;
  const delay = 500;
  const root = document.querySelector('.pills');

  const appendBatch = (from) => {
    for(let i = 0; i < batchSize; i++){
      const element = document.createElement('div');
      element.classList.add('pill');
      element.innerText = String(from + i);

      root.appendChild(element);
    }
  } 

  for(let i = 0; i < 3; i++){
    setTimeout(() => appendBatch(startingIdx + i*batchSize), i*delay);
  }
.pills {
      display: flex;
      gap: 20px;

      width: 100%;
      overflow: auto;

      scroll-snap-type: x mandatory;
    }

    .pill {
      width: 120px;
      height: 40px;
      background: rgba(92, 138, 255, 0.15);
      display: flex;
      align-items: center;
      justify-content: center;
      border-radius: 20px;
      flex-shrink: 0;

      scroll-snap-align: start;
    }
<main>
    <div class="pills">
      <div class="pill">1</div>
      <div class="pill">2</div>
    </div>
  </main>

And the demo where you can reproduce it yourself: https://977940.playcode.io/

This is what I'm talking about

Demo

LosYear
  • 423
  • 2
  • 6
  • 14

2 Answers2

0

Just add that in your script. When page is loaded it scrolls to the left side.

window.addEventListener("DOMContentLoaded", () => {
    root.scrollLeft = 0;
});
Lukas
  • 2,263
  • 1
  • 4
  • 15
  • It won't work since the initial position of scrollLeft is zero and scroll happens later, when elements are inserted – LosYear Oct 05 '22 at 11:46
  • inital position is second element position because you set scroll-snap-align: start; and it default scroll to last element with it. – Lukas Oct 05 '22 at 11:49
0

Seems like adding scroller.scrollBy(0,0); before every batch insertion would save the day as it forces browser to snap to existing element

Source: https://web.dev/snap-after-layout/#interoperability

LosYear
  • 423
  • 2
  • 6
  • 14