{"id":22348901,"url":"https://github.com/remino/scrollerful","last_synced_at":"2025-08-08T04:12:16.111Z","repository":{"id":144920970,"uuid":"582965057","full_name":"remino/scrollerful","owner":"remino","description":"Small JS \u0026 CSS library for scroll animations","archived":false,"fork":false,"pushed_at":"2025-05-28T11:10:10.000Z","size":1510,"stargazers_count":7,"open_issues_count":3,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-07-22T23:52:54.261Z","etag":null,"topics":["animation","css","javascript","scroll","scroll-animation"],"latest_commit_sha":null,"homepage":"https://remino.net/scrollerful/","language":"Sass","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/remino.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-12-28T11:15:32.000Z","updated_at":"2025-07-06T13:45:12.000Z","dependencies_parsed_at":"2025-05-28T12:20:56.264Z","dependency_job_id":"8a71c3e9-e5e1-4d00-9c7b-8ff0f2dbc7ec","html_url":"https://github.com/remino/scrollerful","commit_stats":null,"previous_names":[],"tags_count":18,"template":false,"template_full_name":"remino/template-js","purl":"pkg:github/remino/scrollerful","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remino%2Fscrollerful","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remino%2Fscrollerful/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remino%2Fscrollerful/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remino%2Fscrollerful/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/remino","download_url":"https://codeload.github.com/remino/scrollerful/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remino%2Fscrollerful/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":269361740,"owners_count":24404401,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-08T02:00:09.200Z","response_time":72,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["animation","css","javascript","scroll","scroll-animation"],"created_at":"2024-12-04T11:06:46.259Z","updated_at":"2025-08-08T04:12:16.059Z","avatar_url":"https://github.com/remino.png","language":"Sass","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Scrollerful\n\nBy Rémino Rem \u003chttps://remino.net\u003e\n\nJavaScript library using CSS variables to animate elements while user scrolls.\n\n⚠️ **2025-05-28:** If you only want scroll animations in CSS and you don't need\nto add JavaScript knowing the position of the scroll, I recommend you also look\ninto the\n[Scroll-driven Animations module in CSS](https://drafts.csswg.org/scroll-animations-1/)\nnow supported by Chrome. There is also a\n[polyfill](https://github.com/flackr/scroll-timeline) for browsers that don't\nyet support it, like Firefox and Safari, but doesn't work for all cases.\n\n[Demo](https://remino.net/scrollerful/) |\n[Code](https://github.com/remino/scrollerful/)\n\n- [About](#about)\n  - [What is it?](#what-is-it)\n  - [How does it work?](#how-does-it-work)\n  - [Built With](#built-with)\n- [Getting Started](#getting-started)\n  - [Via CDN](#via-cdn)\n  - [Via npm](#via-npm)\n  - [Download](#download)\n- [Usage](#usage)\n- [Tips](#tips)\n  - [Control when the animation starts and ends](#control-when-the-animation-starts-and-ends)\n  - [Applying multiple animations with different timings](#applying-multiple-animations-with-different-timings)\n  - [Animating only when the container covers the viewport](#animating-only-when-the-container-covers-the-viewport)\n  - [Limited support for the new `animation-timeline`](#limited-support-for-the-new-animation-timeline)\n  - [Horizontal scrolling](#horizontal-scrolling)\n  - [Snapping](#snapping)\n  - [Make the whole page the container](#make-the-whole-page-the-container)\n  - [Make sprites animate but without the floater](#make-sprites-animate-but-without-the-floater)\n  - [Animating the `\u003cbody\u003e` itself.](#animating-the-body-itself)\n- [Contributing](#contributing)\n- [License](#license)\n- [Contact](#contact)\n\n## About\n\nhttps://github.com/remino/scrollerful/assets/29999/9dba06bb-6cc7-434c-8ad0-a56101809890\n\n### What is it?\n\n**Scrollerful** is a tiny JavaScript library of around 1 KB brotlied that works\nwith some stylesheet it inserts in the HTML to control CSS animations while\nscrolling.\n\n### How does it work?\n\n1. You set a _floater_ in a _container_ with _sprites_ (or elements) to animate.\n2. When you scroll, the library checks to see how much of the container has been\n   scrolled in and out the viewport, while the floater with its sprites remains\n   entirely visible.\n3. The library sets some CSS variables to indicate how much as been scrolled and\n   what point of the animation should be displayed, effectively animating\n   sprites will scrolling.\n\n[Back to top](#scrollerful)\n\n### Built With\n\n- JavaScript\n- [Sass](https://sass-lang.com)\n- [rollup.js](https://rollupjs.org/guide/en/)\n- Docs:\n  - [Middleman](https://middlemanapp.com)\n  - [mansite](https://github.com/remino/mansite)\n\n[Back to top](#scrollerful)\n\n\u003c!-- GETTING STARTED --\u003e\n\n## Getting Started\n\nThere are some ways to get **Scrollerful**:\n\n### Via CDN\n\nLink its auto-start script via `unpkg.org`:\n\n```html\n\u003cscript\n  defer\n  src=\"https://unpkg.com/scrollerful@1.0.0/dist/scrollerful-auto.min.js\"\u003e\u003c/script\u003e\n```\n\n### Via npm\n\nGet it via `npm`:\n\n```sh\nnpm add scrollerful\n```\n\nThe package comes with ES and CommonJS modules, which you can import in your\ncode:\n\n```js\n// Using ES6 import\nimport scrollerful from 'scrollerful'\n\n// Using CommonJS require\nconst scrollerful = require('scrollerful')\n\n// Start it\nscrollerful()\n```\n\n### Download\n\nYou can simply\n[get the package on GitHub](https://github.com/remino/scrollerful) or clone the\nrepo from there. The script is bundled as modules both in CommonJS and ES\nformats. [Back to top](#scrollerful)\n\n## Usage\n\n**Step 1.** Define your HTML:\n\n```html\n\u003cdiv class=\"sclf\"\u003e\n  \u003cdiv class=\"sclf__float\"\u003e\n    \u003cdiv class=\"bg sclf__sprite\"\u003e\u003c/div\u003e\n    \u003cdiv class=\"toy sclf__sprite--contain\"\u003e\u003c/div\u003e\n  \u003c/div\u003e\n\u003c/div\u003e\n```\n\n**Step 2.** Define your CSS with animation keyframes:\n\n```css\n@keyframes bg {\n  from {\n    background-color: #000;\n  }\n\n  to {\n    background-color: #fff;\n  }\n}\n\n@keyframes toy {\n  from {\n    border-radius: 100%;\n    color: #fff;\n    transform: rotate(0) scale(1);\n  }\n\n  to {\n    border-radius: 0;\n    color: #000;\n    transform: rotate(1turn) scale(1.4);\n  }\n}\n\n.sclf--enabled .bg {\n  animation-name: bg;\n  inset: 0;\n  position: absolute;\n  z-index: -1;\n}\n\n.sclf--enabled .toy {\n  animation-name: toy;\n  height: 6rem;\n  width: 6rem;\n}\n```\n\n**Step 3.** Define your JavaScript to respond to events and start\n**Scrollerful**:\n\n```js\nimport scrollerful from 'scrollerful'\n\nconst SYMBOLS = '🛑✋😳🔶⌛🏃🤔💭😃👍✅'\nconst symbol = percentage =\u003e SYMBOLS[Math\n    .round(percentage / SYMBOLS.length)]\nconst clamp = (val, min, max) = Math\n    .max(min, Math.min(max, val))\n\n// Show emoji based on how much has been scrolled:\nconst showContainProgress = ({\n    detail: { progress: { contain: progress } }\n}) =\u003e {\n    document.querySelector('.toy').textContent =\n        symbol(clamp(Math.round(progress * 100), 0, 100))\n}\n\nconst main = () =\u003e {\n    document.querySelector('.sclf')\n        .addEventListener('sclf:scroll', showContainProgress)\n\n    scrollerful()\n}\n\nmain()\n```\n\n**Step 4.** Try it!\n\n[See the above in action](https://remino.net/scrollerful/demo/simple/)\n\n[Back to top](#scrollerful)\n\n## Tips\n\n### Control when the animation starts and ends\n\nYou can set some CSS variables to begin an animation far after scrolling into\nthe container, or finish it before reaching the end.\n\n```css\n.sclf--enabled .toy {\n  /* Start animation when scrolling at a quarter: */\n  --sclf-delay: 25;\n\n  /* End animation when scrolling at three quarters: */\n  --sclf-duration: 75;\n}\n```\n\n### Applying multiple animations with different timings\n\nIt’s doable, but tricky and reserved for the pros. The variables used to control\nsingle animations cannot work with multiple ones. You will also have to manage\nthe `animation-range` for the `animation-timeline` yourself.\n\n```css\n.sclf--enabled .toy {\n  animation-delay:\n    calc(var(--sclf-progress-contain, 0) * -100s + 25s),\n    calc(var(--sclf-progress-contain, 0) * -100s + 50s),\n    calc(var(--sclf-progress-contain, 0) * -100s + 0s);\n\n  animation-duration: 50s, 50s, 25s;\n\n  animation-range:\n    contain 25% contain 75%,\n    contain 50% contain 100%,\n    contain 0% contain 25%;\n}\n```\n\nLet’s take the values for the first animation above for example:\n\n1. Every second here is a percent of scrolling of the sprite’s container.\n2. Its delay is set to 25 seconds, so starts when scrolling at 25%.\n3. Its duration is set to 50 seconds, so plus the delay, ends when reaching 75%.\n4. As a `contain` sprite is animated only when the container fills the viewport,\n   its matching `animation-range` should be when the sprite’s container is\n   `contain`ed within the viewport, from 25% to 75%. Thus\n   `contain 25% contain 75%`. (For `cover` sprites, it would be `cover` instead\n   of `contain`.)\n\nNote: if you only set one animation, or all your animations have the same delay\nand duration, this library takes care of that for you.\n\n### Animating only when the container covers the viewport\n\nThere are two kinds of sprites: `cover` and `contain`. For `cover`, the default,\nanimate the moment we see any glimpse of its container. As for `contain`, the\nanimation only begins when the container covers the whole viewport, i.e. when\nits top reaches the top of the browser’s window.\n\n### Limited support for the new `animation-timeline`\n\nCSS scroll animations are coming with `animation-timeline` and a handful of\nother properties.\n\nTo improve animation performance, this library automatically works with then if\nthe browser supports it.\n\nHowever, keep in mind that the specs for\n[CSS scroll animations](https://wiki.csswg.org/ideas/timelines) may change. At\nthe moment, only Chrome support them by default, and Firefox as well when its\n`layout.css.scroll-driven-animations.enabled` flag is enabled.\n\nThat said, `animation-timeline` cannot emit events like **Scrollerful**\ndoes—that’s exclusive to JavaScript.\n\n### Horizontal scrolling\n\nYou can achieve horizontal scrolling (scrolling along the X axis) by wrapping\ncontainers in an element with the `sclf--x` CSS, or simply adding that class in\nthe `\u003cbody\u003e`:\n\n```html\n\u003cbody class=\"sclf--x\"\u003e\n  \u003cdiv class=\"sclf\"\u003e\n    \u003cdiv class=\"sclf__float\"\u003e\n      \u003cdiv class=\"bg sclf__sprite\"\u003e\u003c/div\u003e\n      \u003cdiv class=\"toy sclf__sprite--contain\"\u003e\u003c/div\u003e\n    \u003c/div\u003e\n  \u003c/div\u003e\n\u003c/body\u003e\n```\n\n### Snapping\n\nYou can enable snapping to the edges of containers by adding the `sclf--snap`\nclass to `\u003chtml\u003e`:\n\n```html\n\u003chtml class=\"sclf--snap\"\u003e\u003c/html\u003e\n```\n\nHowever, while it works fine in Firefox and Safari, that looks broken in Chrome.\n(Yeah, I know that’s not good.)\n\n### Make the whole page the container\n\nYou can! Just set the `sclf` class on `\u003cbody\u003e`:\n\n```html\n\u003cbody class=\"sclf\"\u003e\u003c/body\u003e\n```\n\n### Make sprites animate but without the floater\n\nThe floater is optional. If you want to put sprites all over the page and just\nhave them animate in place, just omit it. For example:\n\n```html\n\u003cdiv class=\"sclf\"\u003e\n  \u003cdiv class=\"bg sclf__sprite\"\u003e\u003c/div\u003e\n  \u003cdiv class=\"toy sclf__sprite--contain\"\u003e\u003c/div\u003e\n\u003c/div\u003e\n```\n\n### Animating the `\u003cbody\u003e` itself.\n\nYou can animate the `\u003cbody\u003e` itself by adding the `sclf__sprite` class thus\nturning it into a sprite:\n\n```html\n\u003cbody class=\"sclf__sprite\"\u003e\u003c/body\u003e\n```\n\n```css\n.sclf--enabled body {\n  animation-name: bg;\n}\n\n/* Ensure the \u003chtml\u003e has a proper flexible height. */\nhtml {\n  min-height: 100%;\n}\n```\n\n[Back to top](#scrollerful)\n\n## Contributing\n\nContributions are what make the open source community such an amazing place to\nlearn, inspire, and create. Any contributions you make are **greatly\nappreciated**.\n\nIf you have a suggestion that would make this better, please fork the repo and\ncreate a pull request. You can also simply open an issue with the tag\n\"enhancement\". Don't forget to give the project a star! Thanks again!\n\n1. Fork the Project\n2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`)\n3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`)\n4. Push to the Branch (`git push origin feature/AmazingFeature`)\n5. Open a Pull Request\n\n[Back to top](#scrollerful)\n\n## License\n\nDistributed under the ISC License. See `LICENSE.txt` for more information.\n\n[Back to top](#scrollerful)\n\n## Contact\n\nRémino Rem https://remino.net/\n\n[Back to top](#scrollerful)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fremino%2Fscrollerful","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fremino%2Fscrollerful","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fremino%2Fscrollerful/lists"}