This can be achieved by marking each of the divs you want to scroll in parallel with a certain class, and every individual one with a distinct id. Then you add an event listener for the "scroll" event on every such div, and make the scroll settings of the other divs match the one that triggered the event listener.
const allNodes = Array.from(document.querySelectorAll('.parallel-scroll'));
allNodes.forEach(node => {
const otherNodes = allNodes.filter(x => x.id !== node.id);
node.addEventListener('scroll', e => {
const scrollLeft = e.target.scrollLeft
otherNodes.forEach(x => x.scrollTo(scrollLeft, 0));
});
});
.parent {
display: flex;
flex-direction: column;
gap: 30px;
}
.overflow-x-scroll {
overflow-x: scroll;
}
.container {
display: flex;
gap: 20px;
}
.container > * {
flex-shrink: 0;
}
.red {
background: red;
width: 100px;
height: 100px;
}
<div class="parent">
<div class='overflow-x-scroll parallel-scroll' id='1'>
<div class="container">
<div class="red"></div>
<div class="red"></div>
<div class="red"></div>
<div class="red"></div>
<div class="red"></div>
<div class="red"></div>
<div class="red"></div>
<div class="red"></div>
<div class="red"></div>
<div class="red"></div>
<div class="red"></div>
<div class="red"></div>
<div class="red"></div>
<div class="red"></div>
<div class="red"></div>
<div class="red"></div>
</div>
</div>
<div class='overflow-x-scroll parallel-scroll' id='2'>
<div class="container">
<div class="red"></div>
<div class="red"></div>
<div class="red"></div>
<div class="red"></div>
<div class="red"></div>
<div class="red"></div>
<div class="red"></div>
<div class="red"></div>
<div class="red"></div>
<div class="red"></div>
<div class="red"></div>
<div class="red"></div>
<div class="red"></div>
<div class="red"></div>
<div class="red"></div>
<div class="red"></div>
</div>
</div>
</div>
Optionally, you could configure some kind of debouncing for the listeners (if performance is a problem), but in my experience, it performs well. Also, adding a debouncer may make the controlled scrolling too jittery and affect the user experience negatively.