scroll-behavior: smooth 必须直接作用于可滚动容器(如 .list-container),且需同时设置 height 和 overflow-y: auto;它不继承、不穿透,对 scrolltop 赋值无效,仅响应 scrollto()、scrollby() 和锚点跳转;safari 15.4 前局部容器中静默忽略;需适配 prefers-reduced-motion 降级。

scroll-behavior: smooth 必须作用于滚动容器本身
很多人在 html 或 body 上写 scroll-behavior: smooth,结果局部 div 滚动还是瞬跳——这个属性不继承,也不穿透,只对「显式设置了它的可滚动元素」生效。
要让某个 .list-container 滚动带缓冲,就得直接给它加:
.list-container {
overflow-y: auto;
height: 300px;
scroll-behavior: smooth;
}
- 必须同时满足「有高度 +
overflow-y: auto」,否则scroll-behavior不触发 - Firefox 和 Chrome 支持良好;Safari 15.4 之前在局部容器中会静默忽略,需降级处理
- 该属性对
scrollTop = xxx赋值无效,只响应scrollTo()、scrollBy()和锚点跳转
JS 控制时用 scrollBy({ behavior: 'smooth' }) 更可靠
按钮点击或键盘导航触发滚动时,别手动算 scrollTop 再赋值,容易因重排、缩放、DPI 导致偏移失准。优先用相对滚动 API:
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
const container = document.querySelector('.list-container');
container.scrollBy({ top: 200, behavior: 'smooth' });
-
scrollBy()基于当前状态累加,连点多次不会“跳过”中间帧 - 如果目标是向上滚,传负值:
{ top: -80 },浏览器自动截断边界 - Safari 15.4 以下不支持
behavior: 'smooth'?直接去掉该字段,视觉差异有限,且避免白屏或卡顿
自定义缓动曲线要用 requestAnimationFrame 模拟
原生 scroll-behavior: smooth 只提供一种缓动(cubic-bezier(0.2, 0.6, 0.3, 1)),无法调整节奏。若需更慢启动、更长拖尾,得自己实现:
- 监听
wheel或按钮事件后,e.preventDefault()阻止默认行为 - 用
requestAnimationFrame+ 缓动函数(如easeOutCubic)驱动scrollBy({ behavior: 'auto' }) - 关键点:
behavior: 'auto'必须显式写出,设成'smooth'会打断动画链 - 摩擦系数建议从
0.92起调,越小减速越快,iOS 原生手感接近这个值
系统偏好会强制关闭平滑效果
用户开启「减少运动」系统设置(prefers-reduced-motion: reduce)时,所有浏览器都会自动禁用 scroll-behavior: smooth 和 behavior: 'smooth' ——这不是 bug,是规范要求。
不要试图绕过它,比如用 JS 强行模拟。真正要注意的是:
- 测试时记得在 macOS 系统设置或 iOS 辅助功能里打开「减少运动」验证降级逻辑
- 自定义动画也应监听
@media (prefers-reduced-motion: reduce),改用线性或直接跳转 - 很多团队忽略这点,导致在辅助模式下滚动突然变卡顿,其实只是没做 fallback
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










