{"id":42187407,"url":"https://github.com/barthy-koeln/scroll-snap-slider","last_synced_at":"2026-01-26T22:30:32.575Z","repository":{"id":44871228,"uuid":"301338044","full_name":"barthy-koeln/scroll-snap-slider","owner":"barthy-koeln","description":"Mostly CSS slider with great performance.","archived":false,"fork":false,"pushed_at":"2025-08-24T08:31:04.000Z","size":2613,"stargazers_count":146,"open_issues_count":1,"forks_count":7,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-09-27T08:45:27.070Z","etag":null,"topics":["css","scroll-snapping","slider"],"latest_commit_sha":null,"homepage":"https://barthy-koeln.github.io/scroll-snap-slider/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/barthy-koeln.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","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},"funding":{"github":"barthy-koeln"}},"created_at":"2020-10-05T08:16:05.000Z","updated_at":"2025-09-18T17:25:43.000Z","dependencies_parsed_at":"2024-02-13T09:28:02.467Z","dependency_job_id":"70e754dc-ed26-418d-86f0-a138d5794d47","html_url":"https://github.com/barthy-koeln/scroll-snap-slider","commit_stats":{"total_commits":99,"total_committers":4,"mean_commits":24.75,"dds":0.4949494949494949,"last_synced_commit":"8f9c0d078778e350cf6edbe29fb0fedfbde2d2f6"},"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"purl":"pkg:github/barthy-koeln/scroll-snap-slider","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barthy-koeln%2Fscroll-snap-slider","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barthy-koeln%2Fscroll-snap-slider/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barthy-koeln%2Fscroll-snap-slider/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barthy-koeln%2Fscroll-snap-slider/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/barthy-koeln","download_url":"https://codeload.github.com/barthy-koeln/scroll-snap-slider/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/barthy-koeln%2Fscroll-snap-slider/sbom","scorecard":{"id":226317,"data":{"date":"2025-08-11","repo":{"name":"github.com/barthy-koeln/scroll-snap-slider","commit":"4424f592bcf5f9a4ca20bb23e8908823e8f5bb01"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.5,"checks":[{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":0,"reason":"Found 1/29 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: topLevel 'contents' permission set to 'read': .github/workflows/gh-pages.yml:10","Warn: no topLevel permission defined: .github/workflows/npm-publish.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/gh-pages.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/barthy-koeln/scroll-snap-slider/gh-pages.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/gh-pages.yml:30: update your workflow using https://app.stepsecurity.io/secureworkflow/barthy-koeln/scroll-snap-slider/gh-pages.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/gh-pages.yml:37: update your workflow using https://app.stepsecurity.io/secureworkflow/barthy-koeln/scroll-snap-slider/gh-pages.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/gh-pages.yml:48: update your workflow using https://app.stepsecurity.io/secureworkflow/barthy-koeln/scroll-snap-slider/gh-pages.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/gh-pages.yml:62: update your workflow using https://app.stepsecurity.io/secureworkflow/barthy-koeln/scroll-snap-slider/gh-pages.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/npm-publish.yml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/barthy-koeln/scroll-snap-slider/npm-publish.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/npm-publish.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/barthy-koeln/scroll-snap-slider/npm-publish.yml/main?enable=pin","Info:   0 out of   7 GitHub-owned GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 7 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"10 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-67mh-4wv8-2f99","Warn: Project is vulnerable to: GHSA-mwcw-c2x4-8c55","Warn: Project is vulnerable to: GHSA-vg6x-rcgg-rjx6","Warn: Project is vulnerable to: GHSA-x574-m823-4x7w","Warn: Project is vulnerable to: GHSA-4r4m-qw57-chr8","Warn: Project is vulnerable to: GHSA-xcj6-pq6g-qj4x","Warn: Project is vulnerable to: GHSA-356w-63v5-8wf4","Warn: Project is vulnerable to: GHSA-859w-5945-r5v3"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-17T03:53:39.320Z","repository_id":44871228,"created_at":"2025-08-17T03:53:39.320Z","updated_at":"2025-08-17T03:53:39.320Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28789745,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-26T21:49:50.245Z","status":"ssl_error","status_checked_at":"2026-01-26T21:48:29.455Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["css","scroll-snapping","slider"],"created_at":"2026-01-26T22:30:31.904Z","updated_at":"2026-01-26T22:30:32.560Z","avatar_url":"https://github.com/barthy-koeln.png","language":"TypeScript","funding_links":["https://github.com/sponsors/barthy-koeln"],"categories":[],"sub_categories":[],"readme":"# Scroll Snap Slider\n\n[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)\n[![Maintainability](https://api.codeclimate.com/v1/badges/c4c7edd819ca59e9f5e2/maintainability)](https://codeclimate.com/github/barthy-koeln/scroll-snap-slider/maintainability)\n[![Tree Shaking: Supported](https://badgen.net/bundlephobia/tree-shaking/scroll-snap-slider)](https://bundlephobia.com/result?p=scroll-snap-slider)\n\u003cbr\u003e\n[![npm Version](https://badgen.net/npm/v/scroll-snap-slider)](https://www.npmjs.com/package/scroll-snap-slider)\n[![Dependency Count: 0](https://badgen.net/bundlephobia/dependency-count/scroll-snap-slider)](https://bundlephobia.com/result?p=scroll-snap-slider)\n[![minzipped Size](https://badgen.net/bundlephobia/minzip/scroll-snap-slider)](https://bundlephobia.com/result?p=scroll-snap-slider)\n\nMostly CSS slider with great performance.\n\n[demo](https://barthy-koeln.github.io/scroll-snap-slider/) | [docs](https://barthy-koeln.github.io/scroll-snap-slider/docs/)\n\n## Table of Contents\n\n- [Premise](#premise)\n- [Sizes](#sizes)\n- [Restrictions](#restrictions)\n- [Installing](#installing)\n- [Usage](#usage)\n    - [Markup](#markup)\n    - [CSS](#css)\n    - [Additional Styles](#additional-styles)\n    - [JavaScript](#javascript)\n- [API](#api)\n- [Events](#events)\n- [Public Properties](#public-properties)\n- [Support](#support)\n- [Contributing](#contributing)\n\n## Features\n\n* Native touch integration (draggable)\n* Native scroll integration (any peripheral — if it can scroll, it can use this slider)\n* Full HTML slides (any content possible)\n* Usable with native DOM methods like `scrollIntoView()`\n\n## Premise\n\nThis library is an opinionated minimal implementation of a common feature across many websites.\nTo keep it small, there are not many fancy features and there is almost no error handling.\n\nHowever, with a clear API and the use of a ES6 class, it can provide a useful base for custom extensions.\n\nWhat this module contains:\n\n* Example markup for a `scroll-snap` slider\n* CSS default styling for a `scroll-snap` slider without scrollbars\n* ES6 class to slightly enhance functionality\n* ES6 class plugins for `loop`, `autoplay`, and desktop/mouse `draggable` features\n* TypeScript Typings\n\n## Sizes\n\nHere are the sizes of individual modules, using terser and gzip with default options.\n\n| Item             | minified (terser) | minified + gzipped |\n|------------------|-------------------|--------------------|\n| complete exports | 8.4 kB            | 2.1 kB             |\n\n## Restrictions\n\nThis library only handles sliders on the X-axis.\n\nFor more \"fully-featured\" implementations, go to:\n\n* [Nick Piscitelli's Glider.js](https://github.com/NickPiscitelli/Glider.js)\n* [Tanner Hodges' snap-slider](https://tannerhodges.github.io/snap-slider/)\n\n## Installing\n\n```shell\nnpm install scroll-snap-slider \n\nyarn add scroll-snap-slider\n```\n\n## Usage\n\nThe class provided in this package augments a slider with a few events and methods.\n\n### Markup\n\nYou can add whatever markup inside the slides.\n\n```html\n\n\u003cul class=\"scroll-snap-slider\"\u003e\n  \u003cli class=\"scroll-snap-slide\"\u003e\n    \u003cimg\n      alt=\"\"\n      src=\"https://picsum.photos/id/1011/400/300\"\n    /\u003e\n  \u003c/li\u003e\n  \u003cli class=\"scroll-snap-slide\"\u003e\n    \u003cimg\n      alt=\"\"\n      src=\"https://picsum.photos/id/1018/400/300\"\n    /\u003e\n  \u003c/li\u003e\n\u003c/ul\u003e\n```\n\n### CSS\n\n```css\n@import 'scroll-snap-slider';\n```\n\n### Additional Styles\n\nPrevents page navigation on horizontal scrolling, i.E. on macOS.\n[\\[Support tables\\]](https://caniuse.com/?search=overscroll-behavior)\n\n```css\n.scroll-snap-slider {\n  overscroll-behavior-x: none;\n  overscroll-behavior-y: auto;\n}\n```\n\nPrevents scrolling past elements in the slider:\n[\\[Support tables\\]](https://caniuse.com/?search=scroll-snap-stop)\n\n```css\n.scroll-snap-slide {\n  scroll-snap-stop: always;\n}\n```\n\n### JavaScript\n\nIf you do not want to add any additional behaviour, the JavaScript instance is not needed. This class dispatches several\nevents and exposes a few methods, with which you can enhance your slider's behaviour.\n\n**Default behaviour:**\n\n```javascript\nimport { ScrollSnapSlider } from 'scroll-snap-slider'\n\nconst element = document.querySelector('.example-slider')\nconst slider = new ScrollSnapSlider({ element })\n\nslider.addEventListener('slide-start', function (event) {\n  console.info(`Started sliding towards slide ${event.detail}.`)\n})\n\nslider.addEventListener('slide-pass', function (event) {\n  console.info(`Passing slide ${event.detail}.`)\n})\n\nslider.addEventListener('slide-stop', function (event) {\n  console.info(`Stopped sliding at slide ${event.detail}.`)\n})\n```\n\n**Advanced config:**\n\n```javascript\nimport { ScrollSnapSlider } from 'scroll-snap-slider'\n\n// Do not automatically attach scroll listener\nconst slider = new ScrollSnapSlider({\n  element: document.querySelector('.example-slider'),\n  scrollTimeout: 50, // Sets a shorter timeout to detect scroll end\n  roundingMethod: Math.round, // Dispatch 'slide-pass' events around the center of each slide\n  // roundingMethod: Math.ceil, // Dispatch 'slide-pass' events as soon as the next one is visible\n  // roundingMethod: Math.floor, // Dispatch 'slide-pass' events only when the next one is fully visible\n  sizingMethod (slider) {\n\n    // with padding\n    return slider.element.firstElementChild.offsetWidth\n\n    // without padding\n    // return slider.element.firstElementChild.clientWidth\n  }\n})\n```\n\n**Plugins:**\n\nYou can add one or multiple of the available Plugins:\n\n* `ScrollSnapAutoplay`: Automatically slides at a given interval\n* `ScrollSnapLoop`: Sliding past the last element shows the first without sliding to the start (and vice-versa)\n* `ScrollSnapDraggable`: Drag the slider with your mouse. Note: this does not affect mobile behaviour and is not\n  necessary for touch sliding.\n\n```javascript\nimport { ScrollSnapSlider, ScrollSnapAutoplay, ScrollSnapLoop } from 'scroll-snap-slider';\n\nconst element = document.querySelector('.example-slider')\nconst slider = new ScrollSnapSlider({ element }).with([\n  new ScrollSnapAutoplay(1200),\n  new ScrollSnapLoop\n])\n```\n\nCreating your own plugin:\n\n```javascript\nexport class CustomPlugin extends ScrollSnapPlugin {\n\n  /**\n   * Pass any config here\n   * @param {*} config\n   */\n  constructor (config) {\n    super()\n\n    this.config = config\n  }\n\n  /**\n   * Chose a unique plugin name. If you need multiple instances of the same plugin on a slider, each must return a unique id.\n   * @return {String}\n   */\n  get id () {\n    return 'lubba-wubba-dub-dub'\n  }\n\n  /**\n   * Attach listeners, fetch DOM things, save reference to the slider\n   * @param {ScrollSnapSlider} slider\n   * @override\n   */\n  enable (slider) {\n    // TODO method stub\n  }\n\n  /**\n   * Free resources, remove listeners, ...\n   * @override\n   */\n  disable () {\n    // TODO method stub\n  }\n}\n```\n\n## API\n\n| Method                         | Description                                                                 |\n|--------------------------------|-----------------------------------------------------------------------------|\n| `slideTo(index: Number): void` | Scrolls to slide at `index`.                                                |\n| `addEventListener(...)`        | This is a shortcut for `slider.element.addEventListener(...)`.              |\n| `removeEventListener(...)`     | This is a shortcut for `slider.element.removeEventListener(...)`.           |\n| `attachEventListeners()`       | Enables the JS behaviour of this plugin. This is called in the constructor. |\n| `detachEventListeners()`       | Disables the JS behaviour of this plugin.                                   |\n| `destroy()`                    | Free resources and listeners. You can/should do `slider = null` after this. |\n\n## Events\n\nEvents dispatched on the slider's `element`:\n\n| Event Name    | Event Detail Type | Description                                                                                                                                  |\n|---------------|-------------------|----------------------------------------------------------------------------------------------------------------------------------------------|\n| `slide-start` | `Number`          | Dispatched when sliding starts toward slide at `event.detail`.                                                                               |\n| `slide-pass`  | `Number`          | Dispatched when sliding passes (crosses the threshold to) slide at `event.detail`. The threshold is defined/altered by the `roundingMethod`. |\n| `slide-stop`  | `Number`          | Dispatched when sliding stopped at index `event.detail`, i.e. the last scroll event happened before `scrollTimeout` ms.                      |\n\nYou can use the proxy methods `addEventListener` and `removeEventListener` to listen to them.\n\nIf you want proper typing for these events in TypeScript, you can augment the global `HTMLElementEventMap` interface:\n\n```ts\ndeclare global {\n  interface HTMLElementEventMap {\n    'slide-pass': CustomEvent\u003cnumber\u003e;\n    'slide-stop': CustomEvent\u003cnumber\u003e;\n    'slide-start': CustomEvent\u003cnumber\u003e;\n  }\n}\n```\n\nor copy/import them from `scroll-snap-slider/global.d.ts`.\n\n## Public Properties\n\n| Property                                 | Description                                                           |\n|------------------------------------------|-----------------------------------------------------------------------|\n| `slide: Number` (read only)              | Currently active slide.                                               |\n| `element: Element` (read only)           | The element passed into the constructor.                              |\n| `scrollTimeout: Number`                  | Timeout delay in milliseconds used to catch the end of scroll events. |\n| `plugins: Map\u003cString, ScrollSnapPlugin\u003e` | Map of plugins enabled for this slider                                |\n\n## Support\n\nCheck out the [support tables for CSS scroll snap](https://caniuse.com/css-snappoints).\nNote that it's up to you to inject or add vendor specific code.\n\n## Contributing\n\nFeel free to open issues and pull requests, but keep the minimalist approach of this project in mind. When in doubt,\nopen an issue first and we can discuss.\n\n### Running locally\n\n```shell\nyarn # install deps\nyarn dev # run a local dev-server of the demo\nyarn build # build the module \n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbarthy-koeln%2Fscroll-snap-slider","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbarthy-koeln%2Fscroll-snap-slider","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbarthy-koeln%2Fscroll-snap-slider/lists"}