>_ DevTrendszh

语言

首页

语言

板块

前端 后端 移动端 DevOps AI / ML 游戏开发 区块链 嵌入式 安全
TypeScript

如何实现真正流畅的网站滚动效果而不影响无障碍访问

你是否曾访问过这样的网站,滚动感觉要么"黏稠",要么恰恰相反,太过突兀?设计师喜欢平滑滚动,因为它能为界面增添精致感和高级感。但对开发者来说,这往往变成噩梦:标准的平滑滚动库经常破坏原生导航,与 position: sticky 冲突,或导致浏览器帧率下降。

最近我发现了 darkroom.engineering 团队开发的 Lenis。这些人采用了不同的方法:不是完全替换浏览器行为,而是创建了一个轻量级层,在原生滚动之上工作。

普通库的主要问题是什么

大多数平滑滚动工具只是"禁用"标准滚动并尝试通过变换(CSS 变换)来模拟。这会导致键盘焦点、页面搜索(Cmd+F)和屏幕阅读器功能出现问题。

Lenis(源自拉丁语——"平滑")保留了原生滚动。这意味着你的 anchor links 将正常工作,浏览器仍然能准确理解用户在页面上的位置。另外,这个库只有几 KB,不会引入大量依赖。

Lenis 能做什么

这个库同时解决了多个前端开发者的痛点。

与 WebGL 和动画同步

如果你正在构建复杂的视差效果或将滚动绑定到画布(WebGL),你需要滚动位置的单一数据源。Lenis 与 GSAP ScrollTrigger 配合得非常好。根据我的经验,这是避免元素在快速滚动时"抖动"最稳定的方式。

支持任意轴向

你可以为垂直、水平甚至嵌套滚动配置平滑度。后者特别有用:通常你需要主页平滑滚动,而其中的某些模态块保持自己的行为。

框架支持

虽然我更喜欢用原生 JS 来处理这类事情,但该项目为 React、Vue 甚至 Framer 提供了官方适配器。这节省了传递 refs 和组件生命周期管理的时间。

如何开始使用

安装方式很标准:

npm i lenis

基本初始化就这么简单。你可以启用自动动画循环(autoRaf),这样就不需要手动处理 requestAnimationFrame 了:

import Lenis from 'lenis'
import 'lenis/dist/lenis.css'

const lenis = new Lenis({
  autoRaf: true,
});

// Можно подписаться на события, если нужно обновлять свои анимации
lenis.on('scroll', (e) => {
  console.log('Текущая позиция:', e.scroll);
});

如果你正在使用 GSAP(对于酷炫网站来说,这是事实上的标准),集成会更复杂一些,但也更可靠:

const lenis = new Lenis();

lenis.on('scroll', ScrollTrigger.update);

gsap.ticker.add((time) => {
  lenis.raf(time * 1000);
});

gsap.ticker.lagSmoothing(0);

细节和局限性

尽管它很强大,Lenis 也有其特点。例如,在 Safari 中,帧率更新可能被限制在 60 FPS(低功耗模式下甚至只有 30 FPS),这在高刷新率显示器上有时会很明显。

另一个问题是—— iframe。iframe 内部的滚动不会平滑,因为它们不会将鼠标滚轮事件冒泡出去。这是浏览器的安全限制,库无法解决这个问题。

如果你的页面上有应该正常滚动的元素(如文本字段或下拉菜单),请使用 data-lenis-prevent 属性。这可以避免奇怪的界面行为。

值得实施吗

如果你正在构建着陆页、作品集或宣传网站,其中美学很重要——绝对值得。Lenis 给你那种"高端"效果,同时不影响无障碍访问。

对于包含大量表格的重型仪表盘或管理面板,我可能会持保留态度。在那里,滚动之上的额外抽象层只会妨碍用户快速浏览数据。

总的来说,它是目前同类工具中最简洁、性能最高的之一。看看他们的 Showcase——其中有真正令人印象深刻的例子,展示了普通滚动如何成为视觉叙事的一部分。

相关项目