Demo
scrollmirror.js.org
Installation
Install the plugin from npm and import it into your bundle:
npm i scrollmirror
import ScrollMirror from "scrollmirror";
Or include the minified production file from a CDN:
<script src="https://unpkg.com/scrollmirror"></script>
Usage Example
Suppose you have the following HTML:
<div class="scrollers">
<div class="scroller">
</div>
<div class="scroller">
</div>
</div>
<style>
.scrollers {
display: grid;
grid-template-columns: 50% 50%;
width: 500px;
}
.scroller {
height: 200px;
overflow: auto;
}
</style>
This is how you would mirror the scroll position between the two div.scroller
:
import ScrollMirror from "scrollmirror";
new ScrollMirror(document.querySelectorAll(".scroller"));
See also this minimal example on CodePen
💡 To mirror the scroll position from and to the window
, you would have to add one of :root
, html
or body
to the selector:
new ScrollMirror(document.querySelectorAll(":root, .scroller"));
new ScrollMirror(document.querySelectorAll("html, .scroller"));
new ScrollMirror(document.querySelectorAll("body, .scroller"));
Options
You can pass in a few additional options to ScrollMirror as the second argument:
new ScrollMirror(document.querySelectorAll(".scroller"), options);
The type signature of the options object:
type Options = {
vertical: boolean;
horizontal: boolean;
debug: boolean;
}
vertical
Type: boolean
, default: true
. Should the vertical scroll position be mirrored?
horizontal
Type: boolean
, default: true
. Should the horizontal scroll position be mirrored?
debug
Type: boolean
, default: true
. Should debug messages be printed to the console?
API
To access ScrollMirror's API, you have to save a reference to the class during instaciation:
const mirror = new ScrollMirror(document.querySelectorAll(".scroller"));
mirror.progress
Get the current scroll progress in the form of { x: number, y: number }
, where both x and y are a
number between 0-1
mirror.progress = value
Set the progress and scrolls all mirrored elements. For example:
mirror.progress = { x: 0.2, y: 0.5 };
mirror.progress = { y: 0.5 };
mirror.progress = 0.5;
mirror.getScrollProgress(element: HTMLElement)
Get the current progress of an element. The element doesn't need to be one of the mirrored elements
const mirror = new ScrollMirror(document.querySelectorAll(".scroller"));
console.log(mirror.getScrollProgress(document.querySelector(":root")));
Motivation
There are already a few libraries out there that do the same thing. But all I could find had some limitations (For example, react-scroll-sync needs React, syncscroll doesn't provide an NPM package).
Also, this simple package gave me an excuse to play around with the tooling involved with creating a robust open source npm
package:
- The demo page is generated using Astro and deployed via Netlify
- Browser testing is being done with PlayWright, using the demo site as the source for the test fixtures
- The source code is written in TypeScript