I would like to build an infinite horizontal scroll that scrolls in both directions – left and right. As user scrolls to the left, new content is prepended to the scrollable element (think scrolling through a schedule history, for example). As they scroll to the right, content is appended.

I have learned that browsers anchor content when scrolling up and down which is fantastic, exactly what I’d expect. The effect of that is that prepending content to the scrolled element anchors user to their current, logical position and the content doesn’t “jump”.

But the anchoring doesn’t seem to work when scrolling left or right. The behavior is as if I set overflow-anchor: none. What can I do to make it work as well as when scrolling up?

let topCounter = 0;
document.querySelector('.scrollable-top').scrollTo({ top: 100 });
document.querySelector('.scrollable-top').onscroll = (event) => {
  if (event.target.scrollTop < 100) {
    let box = document.createElement('div');
    box.className="content-box";
    box.textContent = `${topCounter--}`;
    document.querySelector('.scrollable-top').prepend(box);
  }
};

let leftCounter = 0;
document.querySelector('.scrollable-left').scrollTo({ left: 100 });
document.querySelector('.scrollable-left').onscroll = (event) => {
  if (event.target.scrollLeft < 100) {
    let box = document.createElement('div');
    box.className="content-box";
    box.textContent = `${leftCounter--}`;
    document.querySelector('.scrollable-left').prepend(box);
  }
};
.scrollable-top {
  width: 200px;
  height: 250px;
  overflow-y: auto;
  border: solid 1px black;
}

.scrollable-left {
  display: flex;
  width: 250px;
  overflow-x: auto;
  border: solid 1px black;
}

.content-box {
  flex: 1 0 auto;
  height: 150px;
  width: 150px;
  border: solid 1px red;
  display: flex;
  justify-content: center;
  align-items: center;
}
<div class="scrollable-top">
  <div class="content-box">1</div>
  <div class="content-box">2</div>
  <div class="content-box">3</div>
</div>

<div class="scrollable-left">
  <div class="content-box">1</div>
  <div class="content-box">2</div>
  <div class="content-box">3</div>
</div>

I tried to fix your code and got this option

let leftCounter = -2;
let rightCounter = 2;
document.querySelector('.scrollable-left').scrollTo({ left: 100 });
document.querySelector('.scrollable-left').onscroll = (event) => {
  if (event.target.scrollLeft < 100) {
    let box = document.createElement('div');
    box.className="content-box";
    box.textContent = `${leftCounter--}`;
    document.querySelector('.scrollable-left').prepend(box);
    event.target.scrollLeft += 250
  }
  if ((event.target.scrollWidth - event.target.scrollLeft - 250) < 100) {
    let box = document.createElement('div');
    box.className="content-box";
    box.textContent = `${rightCounter++}`;
    document.querySelector('.scrollable-left').append(box);
  }
};
.scrollable-top {
  width: 200px;
  height: 250px;
  overflow-y: auto;
  border: solid 1px black;
}

.scrollable-left {
  display: flex;
  width: 250px;
  overflow-x: auto;
  border: solid 1px black;
}

.content-box {
  flex: 1 0 auto;
  height: 150px;
  width: 150px;
  border: solid 1px red;
  display: flex;
  justify-content: center;
  align-items: center;
}
<div class="scrollable-left">
  <div class="content-box">-1</div>
  <div class="content-box">0</div>
  <div class="content-box">1</div>
</div>

I think by adding the style direction: rtl; to the .scrollable-left class, this style changes the direction of the scrollbar.

let topCounter = 0;
let scrollableTop = document.querySelector('.scrollable-top');
scrollableTop.scrollTo({ top: 100 });
scrollableTop.onscroll = (event) => {
  if (event.target.scrollTop < 100) {
    let box = document.createElement('div');
    box.className="content-box";
    box.textContent = `${topCounter--}`;
    scrollableTop.prepend(box);
  }
};

let leftCounter = 0;
let scrollableLeft = document.querySelector('.scrollable-left');
scrollableLeft.scrollTo({ left: -100 });
scrollableLeft.onscroll = (event) => {
  if (!event.target.scrollLeft < 100) {
    let box = document.createElement('div');
    box.className="content-box";
    box.textContent = leftCounter--;
    scrollableLeft.append(box);
  }
};
.scrollable-top, .scrollable-left {
  box-sizing: border-box;
}

.scrollable-top {
  width: 200px;
  height: 250px;
  overflow-y: auto;
  border: solid 1px black;
}

.scrollable-left {
  display: flex;
  width: 250px;
  border: solid 1px black;
  
  overflow-x: scroll;
  direction: rtl;
}

.content-box {
  flex: 1 0 auto;
  height: 150px;
  width: 150px;
  border: solid 1px red;
  display: flex;
  justify-content: center;
  align-items: center;
  box-sizing: border-box;
}
<div class="scrollable-top">
  <div class="content-box">1</div>
  <div class="content-box">2</div>
  <div class="content-box">3</div>
</div>

<div class="scrollable-left">
  <div class="content-box">1</div>
  <div class="content-box">2</div>
  <div class="content-box">3</div>
</div>