はじめに
Webサイトを閲覧しているとき、スクロールの感触で「このサイト、なんか良いな」と感じることってありませんか。逆に、カクカクしたスクロールだと、どんなにデザインが良くても残念な印象になってしまいます。
Lenisは、そんなスクロール体験を滑らかにしてくれるJavaScriptライブラリです。「Lenis」はラテン語で「滑らか」を意味するそうで、名前通りの機能を提供してくれます。
GitHubスター12,600以上、月間ダウンロード14万件という実績があり、Grand Theft Auto VI、Microsoft Design、Shopifyなど名だたる企業のサイトで採用されています。これだけのビッグネームが使っているなら、信頼性は申し分ないですね。
特徴・メリット
軽量設計
Lenisの圧縮後のサイズは約3.3KB(Gzip時)。スムーススクロール系のライブラリとしてはかなり軽量です。バンドルサイズを気にする昨今のフロントエンド開発において、この軽さは大きなアドバンテージになります。
入力デバイスの正規化
トラックパッド、マウスホイール、タッチデバイスと、ユーザーが使う入力デバイスはさまざまです。Lenisはこれらを統一的に扱い、どのデバイスでも一貫したスクロール体験を提供してくれます。
個人的には、これが意外と重要なポイントだと思っています。開発者としては「MacBookのトラックパッドだと良い感じなのに、マウスだとなんか違う」みたいな問題を解決してくれるわけですから。
パフォーマンス最適化
WebGLとの同期やパララックス効果など、高度なスクロール連動アニメーションにも対応しています。ネイティブスクロールでは発生しがちなジャンプや遅延を排除し、フラッシュレスなアニメーションを実現します。
主な特徴まとめ
- 軽量(約3.3KB gzipped)
- TypeScript対応
- 垂直・水平スクロール対応
- カスタマイズ可能な補間(lerp)
- WebGL/Three.js連携
- スクロールスナップ風の動作
- アクセシビリティを考慮した設計
- MITライセンス
インストール方法
npmでインストールするのが一般的です。
npm install lenis
yarnやpnpmでも同様にインストールできます。
yarn add lenis
# または
pnpm add lenis
CDNから読み込む場合は以下のように。
<script src="https://unpkg.com/lenis@1.3.15/dist/lenis.min.js"></script>
基本的な使い方
最小構成
まずは最もシンプルな実装から。
import Lenis from 'lenis';
const lenis = new Lenis({
autoRaf: true,
});
lenis.on('scroll', (e) => {
console.log(e);
});
autoRaf: trueを指定すると、内部で自動的にrequestAnimationFrameループを回してくれます。これだけでスムーススクロールが有効になります。
CSSの追加
動作を安定させるために、公式推奨のCSSも追加しておきましょう。
html.lenis, html.lenis body {
height: auto;
}
.lenis.lenis-smooth {
scroll-behavior: auto !important;
}
.lenis.lenis-smooth [data-lenis-prevent] {
overscroll-behavior: contain;
}
.lenis.lenis-stopped {
overflow: hidden;
}
.lenis.lenis-smooth iframe {
pointer-events: none;
}
カスタムRAFループ
より細かい制御が必要な場合は、手動でRAFループを管理できます。
import Lenis from 'lenis';
const lenis = new Lenis();
function raf(time) {
lenis.raf(time);
requestAnimationFrame(raf);
}
requestAnimationFrame(raf);
Three.jsやPixiJSなど、独自のアニメーションループを持つライブラリと組み合わせる場合はこちらの方式が適しています。
主要なオプション
const lenis = new Lenis({
lerp: 0.1, // 補間強度(0〜1、小さいほど滑らか)
duration: 1.2, // スクロール時間(秒)
smoothWheel: true, // ホイールイベントのスムージング
orientation: 'vertical', // スクロール方向
autoRaf: false, // 自動フレーム更新
});
lerpとdurationは排他的な関係で、lerpを指定すると慣性ベース、durationを指定すると時間ベースの動作になります。
実践的なユースケース
特定位置へのスムーススクロール
アンカーリンクやナビゲーションでよく使うパターンです。
import Lenis from 'lenis';
const lenis = new Lenis({ autoRaf: true });
// 要素へスクロール
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', (e) => {
e.preventDefault();
const target = document.querySelector(anchor.getAttribute('href'));
if (target) {
lenis.scrollTo(target, {
offset: -100, // ヘッダー分のオフセット
duration: 1.5,
});
}
});
});
スクロール位置に応じたアニメーション
GSAPやAnime.jsと組み合わせて、スクロール連動アニメーションを実装できます。
import Lenis from 'lenis';
import gsap from 'gsap';
import ScrollTrigger from 'gsap/ScrollTrigger';
gsap.registerPlugin(ScrollTrigger);
const lenis = new Lenis({ autoRaf: true });
// LenisとScrollTriggerを同期
lenis.on('scroll', ScrollTrigger.update);
gsap.ticker.add((time) => {
lenis.raf(time * 1000);
});
gsap.ticker.lagSmoothing(0);
この組み合わせは定番中の定番ですね。スムーススクロールの恩恵を受けながら、GSAPの強力なアニメーション機能を活用できます。
モーダル表示時のスクロール制御
モーダルを開いたときに背景のスクロールを止める、よくある実装です。
import Lenis from 'lenis';
const lenis = new Lenis({ autoRaf: true });
function openModal() {
lenis.stop();
document.querySelector('.modal').classList.add('active');
}
function closeModal() {
lenis.start();
document.querySelector('.modal').classList.remove('active');
}
stop()とstart()で簡単にスクロールの有効/無効を切り替えられます。
水平スクロールの実装
ギャラリーやポートフォリオでよく見る水平スクロールも対応しています。
import Lenis from 'lenis';
const lenis = new Lenis({
orientation: 'horizontal',
wrapper: document.querySelector('.horizontal-wrapper'),
content: document.querySelector('.horizontal-content'),
autoRaf: true,
});
特定要素のスクロール除外
フォームの入力欄など、スムーススクロールを適用したくない要素にはdata-lenis-prevent属性を付けます。
<div data-lenis-prevent>
<textarea>この中はネイティブスクロール</textarea>
</div>
地味ですが、実務では結構使う機能です。
注意点と制限事項
導入前に知っておくべき制限事項もあります。
- CSS scroll-snap非対応: スクロールスナップと併用したい場合は工夫が必要
- Safariは60fps制限: 120Hzディスプレイでも60fpsに制限される
- iframe内スクロール非対応: iframeを跨いだスクロール同期はできない
- iOS 16以下での注意: タッチ操作で予期しない動作が発生する可能性あり
正直なところ、すべてのプロジェクトにスムーススクロールが必要かというと、そうでもありません。コンテンツ中心のシンプルなサイトなら、ネイティブスクロールで十分なケースも多いです。「演出として本当に必要か」を考えた上で導入するのが良いと思います。
まとめ
Lenisは、Webサイトのスクロール体験を向上させたいときの有力な選択肢です。
- 軽量(約3.3KB gzipped)でパフォーマンスへの影響が小さい
- 入力デバイスを問わず一貫したスクロール体験を提供
- WebGL/Three.jsとの連携も容易
- GSAPやAnime.jsとの組み合わせで高度な表現が可能
- シンプルなAPIで導入ハードルが低い
30代になって思うのは、「気づかれないくらい自然なUX」の価値なんですよね。スムーススクロールも、派手に目立つものではなく、サイト全体の品質を底上げする縁の下の力持ち的な存在。Lenisはそういう「さりげない良さ」を実現してくれるライブラリだと感じています。
リッチな演出のあるLPやポートフォリオサイト、WebGLを使ったインタラクティブなサイトを作る機会があれば、ぜひ試してみてください。
