必须将 scroll-behavior: smooth 写在 html 元素上才生效,写在 body 或 div 上无效;window.scrollTo() 需显式传入 { behavior: 'smooth' } 才平滑,scrollTop = 0 仍为瞬移;Safari 14.5 前不支持,需用 feature detection + JS 降级。

直接加 scroll-behavior: smooth 到 html 元素上,就能让所有锚点跳转和 window.scrollTo() 自动变平滑——但别急着复制粘贴,有三个地方初学者最容易卡住。
为什么只写 scroll-behavior: smooth 不一定生效
它必须作用在滚动容器上,而页面级滚动容器是 html 元素(不是 body)。如果写了 body { scroll-behavior: smooth },多数浏览器会忽略。
- 正确写法:
html { scroll-behavior: smooth; } - 错误写法:
body { scroll-behavior: smooth; }(无效)或div.container { scroll-behavior: smooth; }(仅对该 div 内部滚动生效) - 注意:若页面用了
overflow: hidden或position: fixed覆盖了html的默认滚动,该属性也会失效
scrollTop = 0 和 scrollTo({ top: 0, behavior: 'smooth' }) 的区别
前者是强制瞬移,后者才触发平滑动画。很多初学者用 JS 绑定按钮后仍写 document.documentElement.scrollTop = 0,结果白配了 CSS。
- 要平滑回顶,JS 中必须显式调用:
document.documentElement.scrollTo({ top: 0, behavior: 'smooth' }) - 或者更简洁:
window.scrollTo({ top: 0, behavior: 'smooth' })(现代浏览器已统一支持) - 不推荐用
animate()+requestAnimationFrame手写缓动——除非你要精确控制贝塞尔曲线或兼容 IE
移动端 Safari 14 之前不支持 scroll-behavior,怎么保底
Safari 在 iOS 14.5 / macOS Big Sur 11.3 才开始支持,老版本用户点按钮会“咔”一下闪上去。不能只靠 CSS。
立即学习“前端免费学习笔记(深入)”;
- 检查是否支持:
'scrollBehavior' in document.documentElement.style - 不支持时,用
requestAnimationFrame做简易缓动(非 cubic-out 也够用) - 更稳妥的做法:保留一个带
href="#top"的锚点链接,并在页面顶部放<div id="top"></div>,这样即使 JS 失效、CSS 不支持,也能退化为原生跳转
最常被忽略的一点:平滑滚动期间,window.onscroll 事件仍会高频触发,如果你在监听里做了 DOM 操作或重排,可能引发卡顿。需要节流或改用 IntersectionObserver 替代部分逻辑。


















