← 📜 Scroll · 滚动怎么动、长什么样、装得下多少 / scroll-behavior:让跳转滚动从瞬移变平滑 待审核 3 / 9
scroll-behavior · 平滑

scroll-behavior:让跳转滚动从瞬移变平滑

点目录跳到某节、点「回到顶部」、改 location.hash——这些程序 / 导航触发的滚动,默认是瞬间跳变scroll-behavior: smooth 让它带上平滑补间动画,纯 CSS,无需手写 JS 动画。关键前提:它只管程序触发的滚动,用户拖滚动条 / 滚轮永远是即时的,不受它影响。

1 · 一个属性,两个值

  • auto(默认):程序滚动瞬间到位。
  • smooth:程序滚动带动画补间。

设在滚动容器上(对整页就是 html),影响该容器之后所有程序触发的滚动。

2 · 动手:auto vs smooth

点下面的按钮跳到各节。切换 scroll-behavior,感受瞬移与平滑的差别;再打开「JS 显式 behavior」开关,看它如何覆盖 CSS 的设定。

三类「程序触发」的滚动都受 scroll-behavior 影响:element.scrollIntoView()scrollTo() / scrollBy(),以及点击页内 #hash 锚 / 焦点导航跳转。

3 · CSS 与 JS 两条路,谁说了算

CSS 设的是该容器程序滚动的默认行为;而 JS 调用里显式behavior 选项时,以选项为准(逐次调用覆盖 CSS)。上面的开关就是这么干的——容器即便是 auto,只要 JS 传了 behavior: 'smooth',这一次也平滑。

html { scroll-behavior: smooth; }

el.scrollIntoView({ behavior: 'smooth', block: 'start' });
container.scrollTo({ top: 0, behavior: 'smooth' });

4 · 别忘了 prefers-reduced-motion

平滑滚动是动效。对开启了「减少动态效果」的用户,长距离平滑滚动可能引起不适,应退回瞬时:

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

上面 demo 里也会实时显示你当前系统的偏好设置。

5 · 配套:让锚点别被吸顶栏盖住

跳转到锚点时,目标常被页面顶部的固定栏挡住。给滚动容器设 scroll-padding-top(或给目标元素设 scroll-margin-top)即可让落点留出空隙。这两个属性也是 scroll snap 的一部分,详见该页。

6 · 边界与细节

  • 只影响程序 / 导航滚动;用户手动拖动滚动条 / 滚轮始终即时。
  • 设在哪个滚动容器,就管哪个容器的程序滚动;整页统一设在 html 上最稳。
  • 平滑滚动的时长 / 缓动曲线由浏览器决定,CSS 不提供调节;要完全自定义动画仍需 JS。
  • 想知道这段平滑滚动何时结束、好接后续动画?见 scrollTo() 返回 Promise