移动端 scroll-behavior: smooth 兼容性差,需 JS 主动调用 + 运行时行为检测 + 降级兜底;整页滚动必须写在 html 上,局部容器需自身声明且禁用 -webkit-overflow-scrolling: touch;JS 滚动必须显式传 behavior: 'smooth',并注意 DOM 渲染时机与 prefers-reduced-motion 系统设置。

移动端只写 scroll-behavior: smooth 基本没用——iOS Safari 15.4 之前完全不识别,微信 X5 WebView 静默降级,Android Chrome 虽支持但 WebView 容器常被阉割。必须 JS 主动调用 + 运行时检测 + 降级兜底。
scroll-behavior 写在哪才生效
整页滚动必须写在 html 上,body 上无效(尤其 iOS Safari);局部滚动容器(比如 .list { overflow-y: auto; })必须自己加 scroll-behavior: smooth,不能靠继承或父级声明“穿透”过去。
-
html { scroll-behavior: smooth; }是整页锚点跳转唯一可靠位置 - 列表容器要同时满足:
overflow-y: auto+height或max-height+scroll-behavior: smooth - 如果容器用了
-webkit-overflow-scrolling: touch,会直接禁用平滑效果,得删掉 - 别信
@supports (scroll-behavior: smooth),它只测 CSS 解析能力,不反映实际行为
JS 主动滚动必须显式传 behavior: 'smooth'
CSS 的 scroll-behavior 不会影响 JS 调用行为。漏传参数就等于放弃平滑:比如 window.scrollTo(0, 100) 是瞬时跳,必须写成 window.scrollTo({ top: 100, behavior: 'smooth' })。
-
element.scrollIntoView({ behavior: 'smooth', block: 'start' })才生效,默认仍是behavior: 'auto' - 目标在自定义滚动容器内(如
.chat-list),必须指定root: chatListEl,否则滚的是整个 window - Vue/React 动态渲染后立即调用,
offsetTop可能为 0,建议包一层requestAnimationFrame - 某些旧 WebView 对
window.scrollTo({})报TypeError: Illegal invocation,改用document.scrollingElement?.scrollTo()
如何真实检测 smooth 是否可用
不能只查 'scrollBehavior' in document.documentElement.style——这只能说明浏览器认识这个 CSS 属性,不代表 JS API 真的支持 behavior: 'smooth'。
立即学习“前端免费学习笔记(深入)”;
- 真实检测应为:
typeof Element.prototype.scrollIntoView === 'function'+ 实际调用并监听 scroll 事件是否在 100ms 内连续触发 ≥3 次 - 部分 WebView(如旧版 X5)对
{ behavior: 'smooth' }参数完全不识别,也不报错,必须靠行为检测 - 用户开启了系统级
prefers-reduced-motion: reduce,所有平滑行为会被强制禁用,且无任何提示 - iOS Safari ≤15.3 会静默忽略,15.4–16.0 支持但极不稳定,常卡顿或跳帧
最易被忽略的点是:滚动容器的 DOM 渲染时机和系统偏好设置。哪怕代码全对,目标元素还没挂载、或者用户开了“减少动画”,behavior: 'smooth' 就会静默失效,连 warning 都没有。


















