https://cdn.jsdelivr.net/gh/studio-freight/lenis@0.2.28/README.md
[](https://github.com/studio-freight/lenis)
[](https://www.npmjs.com/package/@studio-freight/lenis)
## Introduction
🚧 Still in WIP, API might change with new releases 🚧
This is our take on smooth scroll, lightweight, hard working, smooth as butter scroll. See [Demo](https://lenis.studiofreight.com/)
## Features
- Performant
- Lightweight [(~2Kb gzipped)](https://bundlejs.com/?q=%40studio-freight%2Flenis)
- Run scroll in main thread
- Accessibility (CMD+F page search, keyboard navigation, keep scroll position on page refresh, etc.)
- External RAF
- SSR proof
- Not opinionated
- Tree-shakeable
- Custom scroll easing/duration
| Feature | [Locomotive-scroll](https://github.com/locomotivemtl/locomotive-scroll) | [GSAP ScrollSmoother](https://greensock.com/scrollsmoother/) | [Lenis](https://github.com/studio-freight/lenis) |
| --------------------------- | ----------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
| Native scrollbar | ❌ | ✅ | ✅ |
| Native scroll inputs | ❌ | ✅ | ❌ |
| Normalize scroll experience | ✅ | ❌ | ✅ |
| Accessibility | ❌ | ❌ | ✅ |
| CSS Sticky | ❌ | ❌ | ✅ |
| IntsersectionObserver | ❌ | ❌ | ✅ |
| Open source | ✅ | ❌ | ✅ |
| Built-in animation system | ✅ | ✅ | ❌ |
| Size (gzip) | [12.33KB](https://bundlejs.com/?q=locomotive-scroll) | [26.08KB](https://bundlejs.com/?q=gsap%2FScrollSmoother&treeshake=%5B%7BScrollSmoother%7D%5D) | [2.13kb](https://bundlejs.com/?q=%40studio-freight%2Flenis) |
## Installing
using package manager:
```bash
$ npm i @studio-freight/lenis
```
using scripts:
```htmt
```
## Setup
Basic setup
```js
import Lenis from '@studio-freight/lenis'
const lenis = new Lenis({
duration: 1.2,
easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)), // https://www.desmos.com/calculator/brs54l4xou
direction: 'vertical', // vertical, horizontal
gestureDirection: 'vertical', // vertical, horizontal, both
smooth: true,
mouseMultiplier: 1,
smoothTouch: false,
touchMultiplier: 2,
infinite: false,
})
//get scroll value
lenis.on('scroll', ({ scroll, limit, velocity, direction, progress }) => {
console.log({ scroll, limit, velocity, direction, progress })
})
function raf(time) {
lenis.raf(time)
requestAnimationFrame(raf)
}
requestAnimationFrame(raf)
```
Using custom scroll container
```js
const lenis = new Lenis({
wrapper: NodeElement, // element which has overflow
content: NodeElement, // usually wrapper's direct child
})
```
## Instance settings
| Option | Type | Default | Description |
| ------------------ | ------------- | -------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `wrapper` | `NodeElement` | `window` | Default element which has overflow |
| `content` | `NodeElement` | `document.documentElement` | `wrapper`'s direct child |
| `duration` | `number` | `1.2` | Specifies the duration of the animation |
| `easing` | `function` | `(t) => Math.min(1, 1.001 - Math.pow(2, -10 * t))` | Specifies the rate of change of a specific value, our default is custom but you can pick one from [Easings.net](https://easings.net/en) |
| `direction` | `string` | `vertical` | `vertical` or `horizontal` scrolling. |
| `gestureDirection` | `string` | `vertical` | `vertical`, `horizontal` or `both`. |
| `smooth` | `boolean` | `true` | Enable or disable 'smoothness' |
| `mouseMultiplier` | `number` | `1` | This value is passed directly to [Virtual Scroll](https://github.com/ayamflow/virtual-scroll) |
| `smoothTouch` | `boolean` | `false` | Enable or disable 'smoothness' while scrolling using touch. Note: We have disabled it by default because touch devices native smoothness is impossible to mimic |
| `touchMultiplier` | `number` | `string` | This value is passed directly to [Virtual Scroll](https://github.com/ayamflow/virtual-scroll) |
| `infinite` | `boolean` | `false` | Enable infinite scrolling! |
## Instance Methods
| Method | Description | Arguments |
| -------------------------------------------------------- | ------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `raf(time)` | Must be called every frame for internal usage. | |
| `scrollTo(target,{offset, duration, easing, immediate})` | Scroll to a target. | `target`: can be `Number`, `NodeElement` or `String` (CSS selector).
`offset` : `Number` equivalent to [scroll-padding-top](https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-padding-top).
`duration` : `Number` scroll duration in seconds.
`easing` : `Function`.
`immediate` : ignore duration and easing. |
| `on(id,callback({scroll,limit,velocity,direction}))` | `id` can be any of the following [instance events](#instance-events) to listen. | |
| `stop()` | To pause the scroll | |
| `start()` | To resume the scroll | |
| `destroy()` | To destroy the instance and remove all events. | |
## Instance Events
| Event | Callback Arguments |
| -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `scroll` | `scroll`: returns scroll position.
`limit`: returns scroll limit.
`velocity`: returns scroll velocity.
`direction`: returns `1` or `-1`. |
## Considerations
### Things to consider if you want to add Lenis to your codebase will be listed here.
#### Make sure `scroll-behavior` is set to initial or not set at all (thanks [@thagxt](https://github.com/thagxt))
```css
html {
scroll-behavior: initial;
}
```
#### Keep html and body elements default sized ([see this issue](https://github.com/studio-freight/lenis/issues/10))
```css
html,
body {
min-height: 100%;
height: auto;
}
```
#### Use `data-lenis-prevent` attribute on nested scroll elements. In addition, we advice you to add `overscroll-behavior: contain` on this element.
```html