Skip to content

Vanilla JavaScript micro-library to sync the scroll position of multiple elements on your page πŸ”„

License

Notifications You must be signed in to change notification settings

hirasso/scrollmirror

Repository files navigation

readme-header

Test status License

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">
    <!-- some HTML that forces the element to have overflow -->
  </div>
  <div class="scroller">
    <!-- some HTML that forces the element to have overflow. Different length than the previous .scroller -->
  </div>
</div>
<style>
  .scrollers {
    display: grid;
    grid-template-columns: 50% 50%;
    width: 500px;
  }
  .scroller {
    height: 200px;
    overflow: auto; /* this is important! */
  }
</style>

This is how you would mirror the scroll position between the two div.scroller:

import ScrollMirror from "scrollmirror";
/** Mirror all divs that match the class `.scroller` */
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"));
/** or */
new ScrollMirror(document.querySelectorAll("html, .scroller"));
/** or */
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:

// for both directions
mirror.progress = { x: 0.2, y: 0.5 };
// or only set one direction
mirror.progress = { y: 0.5 };
// or for both directions at once:
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"));
// ...sometime later:
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

About

Vanilla JavaScript micro-library to sync the scroll position of multiple elements on your page πŸ”„

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published