
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
scrollerful
Advanced tools
By Rémino Rem https://remino.net
JavaScript library using CSS variables to animate elements while user scrolls.
⚠️ 2025-05-28: If you only want scroll animations in CSS and you don't need to add JavaScript knowing the position of the scroll, I recommend you also look into the Scroll-driven Animations module in CSS now supported by Chrome. There is also a polyfill for browsers that don't yet support it, like Firefox and Safari, but doesn't work for all cases.
animation-timeline<body> itself.https://github.com/remino/scrollerful/assets/29999/9dba06bb-6cc7-434c-8ad0-a56101809890
Scrollerful is a tiny JavaScript library of around 1 KB brotlied that works with some stylesheet it inserts in the HTML to control CSS animations while scrolling.
There are some ways to get Scrollerful:
Link its auto-start script via unpkg.org:
<script
defer
src="https://unpkg.com/scrollerful@1.0.0/dist/scrollerful-auto.min.js"></script>
Get it via npm:
npm add scrollerful
The package comes with ES and CommonJS modules, which you can import in your code:
// Using ES6 import
import scrollerful from 'scrollerful'
// Using CommonJS require
const scrollerful = require('scrollerful')
// Start it
scrollerful()
You can simply get the package on GitHub or clone the repo from there. The script is bundled as modules both in CommonJS and ES formats. Back to top
Step 1. Define your HTML:
<div class="sclf">
<div class="sclf__float">
<div class="bg sclf__sprite"></div>
<div class="toy sclf__sprite--contain"></div>
</div>
</div>
Step 2. Define your CSS with animation keyframes:
@keyframes bg {
from {
background-color: #000;
}
to {
background-color: #fff;
}
}
@keyframes toy {
from {
border-radius: 100%;
color: #fff;
transform: rotate(0) scale(1);
}
to {
border-radius: 0;
color: #000;
transform: rotate(1turn) scale(1.4);
}
}
.sclf--enabled .bg {
animation-name: bg;
inset: 0;
position: absolute;
z-index: -1;
}
.sclf--enabled .toy {
animation-name: toy;
height: 6rem;
width: 6rem;
}
Step 3. Define your JavaScript to respond to events and start Scrollerful:
import scrollerful from 'scrollerful'
const SYMBOLS = '🛑✋😳🔶⌛🏃🤔💭😃👍✅'
const symbol = percentage => SYMBOLS[Math
.round(percentage / SYMBOLS.length)]
const clamp = (val, min, max) = Math
.max(min, Math.min(max, val))
// Show emoji based on how much has been scrolled:
const showContainProgress = ({
detail: { progress: { contain: progress } }
}) => {
document.querySelector('.toy').textContent =
symbol(clamp(Math.round(progress * 100), 0, 100))
}
const main = () => {
document.querySelector('.sclf')
.addEventListener('sclf:scroll', showContainProgress)
scrollerful()
}
main()
Step 4. Try it!
You can set some CSS variables to begin an animation far after scrolling into the container, or finish it before reaching the end.
.sclf--enabled .toy {
/* Start animation when scrolling at a quarter: */
--sclf-delay: 25;
/* End animation when scrolling at three quarters: */
--sclf-duration: 75;
}
It’s doable, but tricky and reserved for the pros. The variables used to control
single animations cannot work with multiple ones. You will also have to manage
the animation-range for the animation-timeline yourself.
.sclf--enabled .toy {
animation-delay:
calc(var(--sclf-progress-contain, 0) * -100s + 25s),
calc(var(--sclf-progress-contain, 0) * -100s + 50s),
calc(var(--sclf-progress-contain, 0) * -100s + 0s);
animation-duration: 50s, 50s, 25s;
animation-range:
contain 25% contain 75%,
contain 50% contain 100%,
contain 0% contain 25%;
}
Let’s take the values for the first animation above for example:
contain sprite is animated only when the container fills the viewport,
its matching animation-range should be when the sprite’s container is
contained within the viewport, from 25% to 75%. Thus
contain 25% contain 75%. (For cover sprites, it would be cover instead
of contain.)Note: if you only set one animation, or all your animations have the same delay and duration, this library takes care of that for you.
There are two kinds of sprites: cover and contain. For cover, the default,
animate the moment we see any glimpse of its container. As for contain, the
animation only begins when the container covers the whole viewport, i.e. when
its top reaches the top of the browser’s window.
animation-timelineCSS scroll animations are coming with animation-timeline and a handful of
other properties.
To improve animation performance, this library automatically works with then if the browser supports it.
However, keep in mind that the specs for
CSS scroll animations may change. At
the moment, only Chrome support them by default, and Firefox as well when its
layout.css.scroll-driven-animations.enabled flag is enabled.
That said, animation-timeline cannot emit events like Scrollerful
does—that’s exclusive to JavaScript.
You can achieve horizontal scrolling (scrolling along the X axis) by wrapping
containers in an element with the sclf--x CSS, or simply adding that class in
the <body>:
<body class="sclf--x">
<div class="sclf">
<div class="sclf__float">
<div class="bg sclf__sprite"></div>
<div class="toy sclf__sprite--contain"></div>
</div>
</div>
</body>
You can enable snapping to the edges of containers by adding the sclf--snap
class to <html>:
<html class="sclf--snap"></html>
However, while it works fine in Firefox and Safari, that looks broken in Chrome. (Yeah, I know that’s not good.)
You can! Just set the sclf class on <body>:
<body class="sclf"></body>
The floater is optional. If you want to put sprites all over the page and just have them animate in place, just omit it. For example:
<div class="sclf">
<div class="bg sclf__sprite"></div>
<div class="toy sclf__sprite--contain"></div>
</div>
<body> itself.You can animate the <body> itself by adding the sclf__sprite class thus
turning it into a sprite:
<body class="sclf__sprite"></body>
.sclf--enabled body {
animation-name: bg;
}
/* Ensure the <html> has a proper flexible height. */
html {
min-height: 100%;
}
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!
git checkout -b feature/AmazingFeature)git commit -m 'Add some AmazingFeature')git push origin feature/AmazingFeature)Distributed under the ISC License. See LICENSE.txt for more information.
Rémino Rem https://remino.net/
FAQs
Small JS & CSS library for scroll animations.
We found that scrollerful demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.