必须写在html元素上,因为浏览器根滚动容器是html而非body;仅对锚点跳转和scrollintoview()等原生滚动行为生效,js主动滚动需显式传behavior:'smooth',且受系统“减少动画”偏好影响。

直接写 html { scroll-behavior: smooth; } 就行,这是最简、最稳、浏览器支持最好的方式。
为什么必须是 html 而不是 body?
因为实际滚动容器是 html 元素——它承载了整个文档的滚动条。很多项目误写成 body { scroll-behavior: smooth; },在 Safari 和旧版 Chrome 中会完全失效。实测 2026 年主流浏览器(Chrome 128+、Firefox 125+、Safari 17.6+、Edge 128+)都要求作用于 html 才能触发锚点跳转和 window.scrollTo() 的平滑行为。
常见错误现象:
— 点击 #contact 链接仍硬跳
— window.scrollTo({ top: 0, behavior: 'smooth' }) 没动画
— 控制台无报错,但 CSS 不生效
- 检查是否写了
body或其他父级元素,删掉,只留html - 确保没有更高优先级的 CSS 覆盖它(比如 inline style 或 !important 冲突)
- 若页面用
height: 100vh; overflow: hidden;锁死html,那它就不再是滚动容器,该属性彻底无效
scroll-behavior: smooth 哪些操作会响应?
它不只管点击链接,所有通过浏览器原生滚动 API 触发的行为都会走平滑路径:
-
@#@#@#@#@#@#@#@#@#@0(锚点跳转) window.scrollTo({ top: 100, behavior: 'smooth' })element.scrollIntoView({ behavior: 'smooth' })-
element.scrollTop = element.scrollHeight(前提是该元素已设scroll-behavior: smooth)
注意:behavior: 'smooth' 在 JS 方法里是可选参数,但若 CSS 已设全局 html,JS 里不写也能生效;反过来,如果只在 JS 里写而没设 CSS,则仅对该次调用有效。
移动端或低配设备上突然不平滑了?
不是代码问题,而是用户开启了系统级“减少运动”偏好。现代浏览器会自动尊重 @media (prefers-reduced-motion: reduce),此时 scroll-behavior: smooth 会被静默降级为 auto。
如果你的产品对无障碍有明确要求(比如政务/医疗类站点),别强行覆盖这个逻辑。但若确实需要强制平滑(极少数场景),可加覆盖规则:
html {
scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) {
html {
scroll-behavior: auto;
}
}
不过更推荐保持默认行为——强行覆盖反而可能违反 WCAG 2.2 标准。
真正容易被忽略的是:这个属性只对“已渲染且可见”的目标元素生效。React/Vue 中用 v-if 或 show 控制显示时,若跳转发生在组件挂载前,offsetTop 为 0,滚动会失败或偏移。这种时候得配合 useEffect 或 nextTick 延迟执行,而不是改 CSS。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











