scroll-behavior: smooth 必须写在 html 元素上才生效,body 上无效;仅对原生锚点跳转和 scrollintoview() 生效,且 js 调用需显式传参 { behavior: 'smooth' }。

scroll-behavior: smooth 必须写在 html 元素上才生效,写在 body 上基本等于没写。
为什么加了 scroll-behavior: smooth 却没反应
最常见原因是样式作用对象错了。浏览器只把 html 当作页面级滚动容器,body 上的该声明会被忽略——哪怕你看到 body 在动,那也只是视觉错觉,滚动上下文不在它身上。
-
html { scroll-behavior: smooth; }是唯一可靠写法;body { scroll-behavior: smooth; }在所有主流浏览器中均无效 - 如果用了 CSS 重置(比如
* { margin: 0; }),检查是否意外设置了html { height: 100%; overflow: hidden; }等破坏默认滚动上下文的规则 - Next.js、Remix 等 SSR 框架可能注入 wrapper div,需用 DevTools 确认实际滚动根元素是否仍是
html - 目标元素被
display: none或visibility: hidden隐藏时,跳转会静默失败(不报错,也不滚动)
锚点跳转不平滑或根本不动
不是 CSS 写错了,而是 DOM 或触发路径出了问题。该属性只对原生 a[href="#id"] 点击和 scrollIntoView() 生效,不接管路由变更、location.hash 手动赋值或 history.pushState() 后的自动滚动。
- 确保
<a href="#section2"></a>和<h2 id="section2"></h2>的id值**完全一致**:大小写敏感、无空格、无 URL 编码 - Vue/React 动态渲染内容时,必须等组件挂载完成、
id真实存在于 DOM 后再触发点击;可加setTimeout(() => el.scrollIntoView({ behavior: 'smooth' }), 0)延迟执行 - SPA 中路由跳转后不滚动?Vue Router 要配
scrollBehavior函数,React Router v6 要用useEffect+useLocation主动调用el.scrollIntoView({ behavior: 'smooth' }) - 移动端 Safari(iOS 15.4 之前)完全无视该 CSS 属性;iOS 16+ 仅对 JS 调用生效,且仍需显式传参
JS 调用 scrollIntoView() 仍是硬跳
即使 html 上写了 scroll-behavior: smooth,直接调用 el.scrollIntoView() 默认仍是 { behavior: 'auto' },不会自动继承 CSS 行为。
- 必须显式传参:
el.scrollIntoView({ behavior: 'smooth' }) - 不要混用:
html { scroll-behavior: smooth; }+el.scrollIntoView({ behavior: 'smooth' })不会出错,但 JS 参数已足够,CSS 属于兜底,非必需 - 旧版 Safari(≤15.4)和 IE 完全不支持
behavior: 'smooth',需降级为scrollIntoViewIfNeeded()(仅 Safari 支持)或用window.scrollTo()+ requestAnimationFrame 模拟 - 滚动偏移不准?加
block和inline控制对齐:{ behavior: 'smooth', block: 'start' }
移动端和系统偏好导致的失效
这不是 bug,是浏览器主动遵守用户设置或平台限制。iOS Safari 直到 15.4 才开始支持,且部分场景(如 PWA 容器、hybrid WebView)会拦截 hash 变更,让 CSS 彻底失效。
- macOS / Windows 开启「减少动画」(
@media (prefers-reduced-motion: reduce))时,所有scroll-behavior: smooth会被强制禁用 - 某些安卓 WebView 或 Cordova 容器不实现该属性,需检测后降级:
if ('scrollBehavior' in document.documentElement.style) - 目标元素若被
transform、filter或父级overflow: hidden包裹,可能导致滚动定位不准,优先保持锚点在标准文档流中 - 频繁调用(如在
touchmove中)可能卡顿,尤其低端 Android 设备,应避免
真正容易被忽略的是两件事:一是永远先确认滚动容器是不是 html,二是 JS 场景下永远手动传 { behavior: 'smooth' }——CSS 属性不会自动渗透进 JS 调用里。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











