配了五年轮播,今天才发现它的交互从来不需要一行 JS——scroll-snap 把这件事彻底原生化了

写前端的人大概都踩过这个坑——每次要给页面加个轮播图或商品滑条,下意识就是去 npm 找一个库,ship 上去 30KB 的 JS,然后花一个小时调它的配置选项。实际上浏览器早就知道怎么处理横向滚动和精准停止——这件事叫 CSS scroll-snap,它只需要几行 CSS,不需要任何依赖。

最小可用版本:六行代码

核心只需要三个属性:

.carousel {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
}
.carousel > li {
  flex: 0 0 80%;
  scroll-snap-align: start;
}

scroll-snap-type: x mandatory 告诉容器水平方向强制吸附,scroll-snap-align: start 让每个子项停靠时左边缘对齐。配上 overflow-x: auto,移动端直接支持手势滑动,桌面端支持鼠标滚轮和触控板双指滚动。

三个让轮播真正可用的细节

一、让卡片的宽度自适应

固定百分比在窄屏幕上会太宽,用 clamp() 控制更合理:

.product-card {
  flex: 0 0 clamp(240px, 75vw, 360px);
}

这样卡片最小 240px,最大 360px,中间随屏幕宽度弹性缩放。

二、做「偷看隔壁」效果,让体验更流畅

.carousel {
  scroll-snap-type: x mandatory;
  scroll-padding-inline: 24px;
}
.carousel-slide {
  scroll-snap-align: center;
  scroll-margin: 0 8px;
}

scroll-padding-inline: 24px 让吸附位置左右各留 24px 边距,这样每次只露出 80% 的当前卡片和左右各一小条邻居卡片。

三、加了 interactive 元素后键盘导航会失效

这是最容易被忽视的坑:Chrome 在轮播项里有链接或按钮时,会把滚动容器从键盘可聚焦状态中移除,导致用户按方向键无法控制轮播。修复方法是一行 tabindex

<ul class="carousel" tabindex="0" role="list">

tabindex="0" 把键盘焦点还给容器,同时 <ul role="list"> 保持语义——屏幕阅读器看到的还是普通列表,不会误判为轮播组件。

scroll-snap-type:mandatory 和 proximity 怎么选

mandatory 是每次停止必然吸附,适合轮播图这类「一页就是一件事」的场景。proximity 更宽松——只有用户停在接近吸附点的位置才吸附,否则自由滚动,适合商品推荐列表这类「用户可能想快速扫过」的场景:

/* 轮播:每张必须停住 */
.carousel { scroll-snap-type: x mandatory; }

/* 推荐列表:可以快速滑过 */
.recommend-rail { scroll-snap-type: x proximity; }

scroll-snap-stop: always 可以防止快速滑动跳过多张,但它比较新,只有 Chrome 122+ 和 Safari 17+ 支持,建议作为增强而非主逻辑。

性能为什么比 JS 方案更好

所有滚动、减速、吸附的物理运算都跑在浏览器合成器线程,不占用主线程。JS 轮播方案每帧都要用 requestAnimationFrame 算位置,而 CSS scroll-snap 相当于浏览器内置的动画内核,提前做了优化。

另外 CSS-only 方案没有包体积,puredevtools.tools 的测评显示一个基础轮播实现只需要 ~500 字节的 CSS,而主流轮播库 gzip 后普遍在 8KB–30KB 之间。

三步下一步

  1. 找出一个项目里用了轮播库的地方——它大多只是 testimonials、产品卡片或图片条,没有复杂交互,用六行 CSS 替换掉
  2. 加上 scroll-padding-inline——让第一张和最后一张不贴边,给固定导航栏留出空间
  3. 加 tabindex=”0″——如果轮播项里有按钮或链接,必须手动恢复键盘可聚焦性,否则键盘用户无法使用

浏览器兼容性方面,scroll-snap 在 Chrome 69+、Firefox 68+、Safari 11+、Edge 79+ 全部支持,全球覆盖率超过 97%,可以直接上线不用 polyfill。旧浏览器会回退为普通横向滚动,功能降级但不报错。

评论区

0 条评论

登录后可评论。

阿柯·前端架构 16 阅读