{"id":19252724,"url":"https://github.com/morevm/smooth-scroll","last_synced_at":"2026-02-22T21:03:29.533Z","repository":{"id":37029600,"uuid":"485600740","full_name":"MorevM/smooth-scroll","owner":"MorevM","description":"The last script for animated scrolling you ever need","archived":false,"fork":false,"pushed_at":"2024-08-17T18:34:23.000Z","size":622,"stargazers_count":0,"open_issues_count":18,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-02T07:56:19.563Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/MorevM.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE.md","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}},"created_at":"2022-04-26T02:06:54.000Z","updated_at":"2024-05-21T15:12:00.000Z","dependencies_parsed_at":"2024-01-12T20:57:33.398Z","dependency_job_id":"4375a06d-502e-4ea0-a46f-42e00fc03ffe","html_url":"https://github.com/MorevM/smooth-scroll","commit_stats":{"total_commits":17,"total_committers":2,"mean_commits":8.5,"dds":"0.23529411764705888","last_synced_commit":"8b6881a6051b4ea819d9f6c802f7caf3a953ada4"},"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/MorevM/smooth-scroll","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MorevM%2Fsmooth-scroll","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MorevM%2Fsmooth-scroll/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MorevM%2Fsmooth-scroll/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MorevM%2Fsmooth-scroll/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MorevM","download_url":"https://codeload.github.com/MorevM/smooth-scroll/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MorevM%2Fsmooth-scroll/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":281322869,"owners_count":26481547,"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-10-27T02:00:05.855Z","response_time":61,"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":[],"created_at":"2024-11-09T18:28:12.064Z","updated_at":"2025-10-27T18:39:34.223Z","avatar_url":"https://github.com/MorevM.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @morev/smooth-scroll (still WIP)\n\n![Stability of \"master\" branch](https://img.shields.io/github/actions/workflow/status/MorevM/smooth-scroll/build.yaml?branch=master)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n![Last commit](https://img.shields.io/github/last-commit/morevm/smooth-scroll)\n![Release version](https://img.shields.io/github/v/release/morevm/smooth-scroll?include_prereleases)\n![GitHub Release Date](https://img.shields.io/github/release-date/morevm/smooth-scroll)\n![Keywords](https://img.shields.io/github/package-json/keywords/morevm/smooth-scroll)\n\nThe last script for animated scrolling you ever need.\n\n## Table of contents\n\n* [Installation](#installation)\n  * [Using `yarn`](#using-yarn)\n  * [Using `npm`](#using-npm)\n  * [Using `yarn`](#using-pnpm)\n* [Usage](#usage)\n  * [smooth-scroll](#smooth-scroll)\n  * [smooth-scroll-native](#smooth-scroll-native)\n* [Options](#options)\n* [API](#api)\n* [Recipes](#recipes)\n\n## Installation\n\n### Using `yarn`:\n\n```bash\nyarn add @morev/smooth-scroll\n```\n\n### Using `npm`:\n\n```bash\nnpm install @morev/smooth-scroll\n```\n\n### Using `pnpm`\n\n```bash\npnpm add @morev/smooth-scroll\n```\n\n## Usage\n\nThere are two modules you can use: `smooth-scroll` and `smooth-scroll-native`.\n\n### smooth-scroll\n\nUses the `window.requestAnimationFrame`.\n\n#### ES modules\n\n```js\nimport { SmoothScroll } from '@morev/smooth-scroll';\n\nconst scroll = new SmoothScroll({/* custom options */});\nscroll.to('#target-element');\n```\n\n#### CommonJS\n\n```js\nconst { SmoothScroll } = require('@morev/smooth-scroll');\n\nconst scroll = new SmoothScroll({/* custom options */});\nscroll.to('#target-element');\n```\n\n### smooth-scroll-native\n\nUses the native `scrollTo` method with `behavior: smooth`.\n\n#### ES modules\n\n```js\nimport { SmoothScrollNative } from '@morev/smooth-scroll/native';\n\nconst scroll = new SmoothScrollNative({/* custom options */});\nscroll.to('#target-element');\n```\n\n#### CommonJS\n\n```js\nconst { SmoothScrollNative } = require('@morev/smooth-scroll/native');\n\nconst scroll = new SmoothScrollNative({/* custom options */});\nscroll.to('#target-element');\n```\n\n### Vue.js\n\n```js\nimport SmoothScroll from '@morev/smooth-scroll/vue';\n\nVue.use(SmoothScroll, {/* custom options */});\n```\n\n```vue\n\u003ctemplate\u003e\n  \u003cbutton @click=\"scrollTo\"\u003e\u003c/button\u003e\n\u003c/template\u003e\n\n\u003cscript\u003e\n  export default {\n    methods: {\n      scrollTo() {\n        this.$SmoothScroll.to('#target-element');\n      },\n    },\n  };\n\u003c/script\u003e\n```\n\n\u003e Vue module creates the only instance, so if you need multiple instances, you should use `SmoothScroll` directly.\n\n## Options\n\n### element\n\n```ts\n{\n  element: HTMLElement | Window | 'auto'; // default is 'auto'\n}\n```\n\nThe element being scrolled, `window` object, or `auto` for getting the nearest scrollable ancestor element.\n\n\u003e The value `auto` is suitable in most cases, but sometimes it may cause some unexpected behavior,\n\u003e mostly in scenarios involving fixed elements and/or not unique selectors. \\\n\u003e It also does not affects if scroll target is a certain value rather than element. \\\n\u003e So it is recommended to set this option explicitly, and maybe to have separated instances to process the page and inner blocks scrolling.\n\n### duration\n\n```ts\n{\n  duration: number | [number, number];  // default is `[300, 700]`\n}\n```\n\nScroll animation duration.\n\nThis is the number representing the amount of time in milliseconds that it should take to scroll 1000px.\nThe greater the distance, the longer the animation will take (twice as much for 2000px, three times more for 3000px, etc.).\n\nThere can also be supplied an array of two values which first value is duration and second value is duration limit. By default, the limit is 2000ms.\n\nDoes not affects while using `smooth-scroll-native`.\n\n### easing\n\n```ts\n{\n  // Default value: imported `easeInOutQuad` function\n  easing: (time: number, begin: number, change: number, duration: number) =\u003e number;\n}\n```\n\nThe easing function used during the scroll animation.\\\nCan be one of [js-easing-functions](https://github.com/bameyrick/js-easing-functions#available-easing-functions) (included as a dependency).\\\nSee the example [\"Custom animation\"](#custom-animation).\n\nDoes not affects while using `smooth-scroll-native`.\n\n### ifNeeded\n\n```ts\n{\n  ifNeeded: boolean; // default is `false`\n}\n```\n\nWhether to not invoke scrolling if target position is already in viewport.\n\n### autofocus\n\n```ts\n{\n  autofocus: boolean; // default is `false`\n}\n```\n\nWhether to set focus to the target element after scrolling. \\\nAffects only if a given target is an element/selector.\n\n\u003e It is strongly recommended to set this option to `true`, at least while navigating through the page.\n\n### block\n\n```ts\n{\n  block: 'start' | 'end' | 'center'; // default is 'start'\n}\n```\n\nAlignment of the target element after scrolling by x-axis.\\\nAffects only if a given target is an element/selector.\n\n### inline\n\n```ts\n{\n  inline: 'start' | 'end' | 'center'; // default is 'start'\n}\n```\n\nAlignment of the target element after scrolling by y-axis.\\\nAffects only if a given target is an element/selector.\n\n### offset\n\n```ts\n{\n  offset: number | { x: number; y: number; }; // default is `{ x: 0, y: 0 }`\n}\n```\n\nAdditional offset(-s) added to the result position values. \\\nSingle value treats as `Y`-axis offset, with object notation can set `X` and `Y` offsets both.\nAffects only if a given target is an element/selector.\n\n#### offset.x\n\nAdditional offset added to the result x-axis position value.\n\n#### offset.y\n\nAdditional offset added to the result y-axis position value.\n\n### fixedElements\n\n```ts\n{\n  // Empty by default\n  fixedElements: {\n    x: {\n      start: Array\u003cHTMLElement | string\u003e;\n      end: Array\u003cHTMLElement | string\u003e;\n    };\n    y: {\n      start: Array\u003cHTMLElement | string\u003e;\n      end: Array\u003cHTMLElement | string\u003e;\n    };\n  };\n}\n```\n\nA set of HTML elements (or its selectors) whose sizes should be considered in the result position calculation.\\\nAffects only if a given target is an element/selector.\n\n#### fixedElements.x.start\n\nAn array of elements whose sizes should be excluded from the result x-axis position value.\n\n#### fixedElements.x.end\n\nAn array of elements whose sizes should be included to the result x-axis position value.\n\n#### fixedElements.y.start\n\nAn array of elements whose sizes should be excluded from the result y-axis position value.\n\n#### fixedElements.y.end\n\nAn array of elements whose sizes should be included to the result y-axis position value.\n\n## API\n\n### to\n\nSmoothly scrolls to a given target.\n\n**Arguments:**\n\n| Name    | Type                                     | Default | Description                                                                                         |\n|---------|------------------------------------------|---------|-----------------------------------------------------------------------------------------------------|\n| target* | `number\\|number[]]\\|HTMLElement\\|string` | —       | A number (y-value), an array of two numbers (x and y values), HTML element or the element selector. |\n| options | `object`                                 | `{}`    | Custom options, extends the initial options for current invocation.                                 |\n\n**Returns:**\n\n`Promise\u003cnumber[]\u003e` - Promise object representing the array of result `x` and `y` scroll position.\n\n**Example:**\n\n```js\nimport { SmoothScroll } from '@morev/smooth-scroll';\n\nconst scroll = new SmoothScroll();\n\nscroll.to(1000);\nscroll.to([0, 1000]);\nscroll.to(document.querySelector('#target-element'));\nscroll.to('#target-element');\nscroll.to('#target-element', {/* override the initial options */});\n```\n\n### addFixedElements\n\nDynamically adds fixed elements after initialization.\n\n**Arguments:**\n\n| Name       | Type                       | Default | Description                                                                             |\n|------------|----------------------------|---------|-----------------------------------------------------------------------------------------|\n| axis*      | `string`                   | —       | Whether to add the elements to the `x` or `y` category of `fixedElements` option.       |\n| alignment* | `string`                   | —       | Whether to add the elements to the `start` or `end` category of `fixedElements` option. |\n| elements*  | `...(HTMLElement\\|string)` | —       | The elements being added.                                                               |\n\n**Returns:**\n\n`SmoothScroll` - The class instance.\n\n**Example:**\n\n```js\nimport { SmoothScroll } from '@morev/smooth-scroll';\n\nconst scroll = new SmoothScroll();\nscroll.addFixedElements('y', 'start', '.element-one', document.querySelector('.element-two'), '.element-three');\n```\n\n### removeFixedElements\n\nDynamically removes registered fixed elements.\n\n**Arguments:**\n\n| Name      | Type                       | Default | Description                 |\n|-----------|----------------------------|---------|-----------------------------|\n| elements* | `...(HTMLElement\\|string)` | —       | The elements being removed. |\n\n**Returns:**\n\n`SmoothScroll` - The class instance.\n\n**Example:**\n\n```js\nimport { SmoothScroll } from 'smooth-scroll';\n\nconst scroll = new SmoothScroll({\n  fixedElements: {\n    y: {\n      start: [\n        document.querySelector('.element-one'),\n        'element-two',\n      ],\n    },\n  },\n});\n\nscroll.removeFixedElements('.element-one', document.querySelector('.element-two'));\n```\n\n\u003e If one element is used in different categories of the `fixedElements` option, it will be removed everywhere.\n\n## Recipes\n\n### Sticky navigation with anchor links\n\n```js\nimport { SmoothScroll } from '@morev/smooth-scroll';\n\nconst scroll = new SmoothScroll({\n  autofocus: true,\n  fixedElements: {\n    y: {\n      start: ['#sticky-nav.is-fixed'],\n    },\n  },\n});\n\ndocument.addEventListener('click', (e) =\u003e {\n  const link = e.target.closest('#sticky-nav .anchor-link');\n  if (!link) return;\n\n  scroll.to(link.hash);\n  e.preventDefault();\n});\n```\n\n### Custom animation\n\n```js\nimport { SmoothScroll } from '@morev/smooth-scroll';\nimport { easeInQuad } from '@morev/smooth-scroll/easing';\n\nconst scroll = new SmoothScroll({\n  duration: 600,\n  easing: easeInQuad,\n});\n\nscroll.to('#target-element');\n```\n\n### Fixed scroll animation duration\n\n```js\nimport { SmoothScroll } from '@morev/smooth-scroll';\n\nconst scroll = new SmoothScroll({\n  duration: [600, 600], // animation will always take exactly the same amount of time\n});\n\nscroll.to('#target-element');\n```\n\n### Reduced motion mode\n\n```js\nimport { SmoothScroll } from '@morev/smooth-scroll';\n\nconst isMotionless = window.matchMedia('(prefers-reduced-motion: reduce)').matches;\nconst scroll = new SmoothScroll({\n  duration: isMotionless ? 0 : 400,\n});\n\nscroll.to('#target-element');\n```\n\n### Autofocus on the specific element\n\n```js\nimport { SmoothScroll } from '@morev/smooth-scroll';\n\nconst scroll = new SmoothScroll();\nconst target = document.querySelector('#target-element');\n\nscroll.to(target).then(() =\u003e {\n  const needFocus = target.querySelector('.need-focus');\n  needFocus.focus();\n});\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmorevm%2Fsmooth-scroll","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmorevm%2Fsmooth-scroll","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmorevm%2Fsmooth-scroll/lists"}