Skip to content

zdimaz/ScrollVar

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ScrollVar

license Tiny scroll library (~700 bytes gzipped) that maps scroll position to a CSS custom property. All effects live in CSS.

Instead of applying transform directly in JS, ScrollVar writes a single unitless number to a CSS variable. Every visual effect — parallax, fade, hue shift, scale, clip-path — is expressed in CSS. JS stays out of the way.

Live Demo →


Why CSS-driven?

Classic parallax ScrollVar
Where effects live JS CSS
Speed control JS option CSS --speed variable
Media queries JS resize handler Native @media
Effect types Usually only translateY Any CSS property
Multiple effects, one element Multiple classes / instances One variable, many calc()

One new ScrollVar('.section') → unlimited CSS effects, zero JS changes.


Install

Copy scrollvar.js directly into your project — zero dependencies, single file.


Usage

JS — one line:

import ScrollVar from "../scrollvar.js";
new ScrollVar(".hero");

CSS — all the logic:

/* Parallax — speed controlled entirely in CSS */
.hero {
  --speed: 0.15;
  transform: translateY(calc(var(--scroll-offset) * var(--speed) * 1px));
}

/* On mobile — just change the variable */
@media (max-width: 768px) {
  .hero {
    --speed: 0.05;
  }
}

/* Fade on scroll */
.card {
  opacity: clamp(0, calc(1 - abs(var(--scroll-offset)) / 400), 1);
}

/* Hue shift */
.bg {
  filter: hue-rotate(calc(var(--scroll-offset) / 10 * 1deg));
}

/* Scale */
.badge {
  scale: clamp(0.5, calc(1 - abs(var(--scroll-offset)) / 600), 1.2);
}

Variable value

--scroll-offset is a unitless pixel number:

elementCenter − viewportCenter
Value Meaning
0 Element center is at viewport center
negative Element is below viewport center
positive Element is above viewport center

This makes it natural for symmetrical effects like fade and scale: abs(var(--scroll-offset)) is the distance from the sweet spot.


Per-element variable name

Use data-scroll-var when different sections need different variable names:

<section class="hero" data-scroll-var="--hero-offset"></section>
<section class="about" data-scroll-var="--about-offset"></section>
new ScrollVar("[data-scroll-var]");
.hero {
  transform: translateY(calc(var(--hero-offset) * 0.15px));
}
.about {
  opacity: clamp(0, calc(1 - abs(var(--about-offset)) / 300), 1);
}

API

new ScrollVar(selector, options?)

Parameter Type Default Description
selector string | Element | NodeList Elements to track
options.varName string '--scroll-offset' CSS variable name to write
options.onlyVisible boolean true Skip fully off-screen elements

.refresh()

Force an update outside normal scroll/resize events when you need it:

const sv = new ScrollVar(".card");
sv.refresh();

.add(selector, options?)

Add more elements to an existing instance:

const sv = new ScrollVar(".hero");
sv.add(".card", { varName: "--card-offset" });

.destroy()

Remove CSS variables from all elements and stop updates:

sv.destroy();

Browser support

All modern browsers. Requires CSS.supports('--a', '0') — no IE.


License

MIT

About

ScrollVar Add JS once. Control everything through CSS

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors