The overflow-anchor property is not effective for scrolling horizontally

My goal is to create a never-ending horizontal scroll that allows users to scroll both left and right. When users scroll to the left, new content should be added to the beginning of the scrollable element (similar to scrolling through a schedule history). Conversely, when they scroll to the right, content should be appended.

I have noticed that browsers anchor content when scrolling up and down, which works perfectly as expected. This anchoring ensures that prepended content does not cause any sudden jumps in the scrolling experience.

However, the anchoring does not seem to work when scrolling horizontally (left or right). It feels as if the behavior is similar to having `overflow-anchor: none` set. How can I achieve the same smooth scrolling experience when moving left or right?

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>

Answer №1

Move the horizontal container 150 pixels to the right by using the scrollBy(150, 0) method:

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);
    
    // solution ------------------
    event.target.scrollBy(150, 0);
  }
};
.scrollable-top {
  width: 200px;
  height: 250px;
  overflow-y: auto;
  border: solid 1px black;
  display: inline-block;    
  float:left;
}

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

.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>


The purpose of anchoring, as outlined in the specifications, is to ensure a smoother user experience when scrolling through content. By keeping track of an anchor node, the scroll offset can be adjusted to prevent sudden movements of the page while the user is reading.

Changes in DOM elements above the visible region of a scrolling box can result in the page moving while the user is in the middle of consuming the content. This spec proposes a mechanism to mitigate this jarring user experience by keeping track of the position of an anchor node and adjusting the scroll offset accordingly.
This spec also proposes an API for web developers to opt-out of this behavior.

Due to the lack of horizontal page scrolling, the anchoring behavior may not be implemented for horizontal scrollbars. Unless required for specific use cases, implementing this behavior may not be necessary.

Note: Safari does not support the overflow-anchor behavior for vertical scrolling. If you intend to create infinite scroll functionality while ensuring cross-browser compatibility, consider opting out of overflow-anchor and manually using scrollBy(x,y) method for vertical scrolling in Safari.

Answer №2

After making some adjustments to your code, I ended up with the following solution:

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>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Guide to building a hierarchical data object with JavaScript

Prior This object consists of multiple rows: { "functions": [ { "package_id": "2", "module_id": "2", "data_id": "2" }, { "package_id": ...

Adjust the size of the logo as the user scrolls

Currently, I am implementing a JavaScript feature that allows my logo to shrink when the user scrolls down and grow when they scroll up. To achieve this effect, I am utilizing the jQuery functions addClass and removeClass. However, I have encountered som ...

Angular factory transforming service

I am looking to transform the 'i18n' function into a factory in order to return a value instead of just setting it. Any suggestions or tips would be greatly appreciated! services.factory('i18nFactory', function() { var language = ...

Inspecting element value on a website

On a marketplace website, I extracted the attribute (capacity_gold) from a table. Since the values are dynamic and constantly changing, I aim to develop a basic script that will notify me when the attribute value exceeds 100. The current value of the attr ...

Understanding the separation and communication techniques in Vue.js components

I recently developed a small vuejs application and I find myself getting confused with the functioning of components. Here is the code snippet that I have been working on: <div id="app"> <div v-if="loggedIn"> <nav> <r ...

Troubleshooting jQuery compatibility issue in IE6 when using javascript and loading content through ajax

Encountering issues with IE6 and javascript applied to ajax content. Unable to use any type of javascript (plain or with jQuery) on the ajax-retrieved content. The main html page loads the Header content using ajax (specifically utilizing the jQuery ...

What could be causing the <img src= ' '/> tag to malfunction in Express?

While learning about HTML, I noticed that simply using img src="...." worked fine. However, when working with Express, the same code did not work! The documentation mentioned that I needed to place the images in a folder named public, require(&ap ...

Guide on redirecting a webpage post form validation in JavaScript

I have a question about my JavaScript code. Even if validation fails, the contact us page still appears. How can I fix this issue? Appreciate any help. Thank you! (function () { window.addEventListener('load', function () { var forms = do ...

How to build custom middleware with parameters in Node.js

I'm working on creating a middleware in nodejs for access levels, and I've written the following middleware: class AccessUser extends middlware { async AccessUser(access,req, res, next) { const getTokenFrom = (req) => { const autho ...

When attempting to access /test.html, Node.js server returns a "Cannot GET"

Embarking on the journey of diving into Pro AngularJS, I have reached a point where setting up the development environment is crucial. This involves creating an 'angularjs' directory and placing a 'test.html' file in it. Additionally, o ...

Show me a list of all the commands my bot has in discord.js

Recently, I developed a Discord bot using discord.js and attempted to create a help command that would display all available commands to the user. For example, one of the commands is avatar.js module.exports.run = async(bot, message, args) => { le ...

Having trouble with the rendering of the Stripe Element Quickstart example

Currently, I am diving into the world of Stripe's Element Quickstart. Take a look at this fiddle that I have been working on. It seems to be quite different from the example provided. Although I have included the file, I can't seem to figure out ...

Issue with fullcalendar: difficulty displaying events using ajax after clicking 'previous' or 'next' button

I am currently working on creating a calendar using fullcalendar. To retrieve data for the month, I make an external ajax request. Here are the key variables I utilize to render the fullcalendar: eventsJsonArray - used to load all events for the month ...

Contrasting outcomes between calling the await method in a function and directly logging the same method

My code consists of a for loop that iterates through an array. With each iteration, I intend for the loop to extract the value from a specified webpage and then display it in the console. for (let i = 0; i < jsonObjSplit.length; i++) { console ...

What's the best way to search through various addresses for the source in an image tag?

In my current Laravel 5.8 project, I am faced with the task of searching through three different image sources for an img tag. First, I attempt to load the image from "". If that fails, I try a second URL like "". Should both attempts be unsuccessful, I th ...

Is there a way to toggle the slide effect of one 'div' without affecting another one?

Hey everyone! I am new to jquery and currently working on a project with two div elements that are slidetoggled. The issue I am facing is that when I open or close one div, the other div also moves along with it. I understand what is happening in the back ...

Proper method for updating a component prop in Vue.js from within its method

Here is the code snippet for a Vue.js component: var list = Vue.component('list', { props: ['items', 'headertext', 'placeholder'], template: ` <div class="col s6"> <div class="search"> ...

How can I determine if a specific button has been clicked in a child window from a different domain?

Is there a method to detect when a specific button is clicked in a cross-domain child window that cannot be modified? Or determine if a POST request is sent to a particular URL from the child window? Below is an example of the HTML code for the button tha ...

Personalize the position of the v-select drop-down menu

I am currently working with the vuetify v-select component. The problem I am encountering is that instead of the dropdown opening downwards, I need it to open upwards since the dropdown is positioned at the bottom of the page which causes some of the dro ...

Exploring ways to maximize the width of responsive images on a webpage

I am currently working on a website located at . The slider image dimensions are set to 800x400, but the height appears too large. I need assistance in making the slider images responsive while maintaining their full width without sacrificing height. Ple ...