oversmooth 并非标准 CSS 属性,实为 overscroll-behavior 与 scroll-behavior: smooth 的误混;真正影响移动端滑动流畅度的是容器高度确定、合成层提示、passive 事件监听及祖先样式协同。

oversmooth 不是标准 CSS 属性,也不存在于任何浏览器引擎中。你搜到的“oversmooth”大概率是误传、拼写错误,或是把 overscroll-behavior 和 scroll-behavior: smooth 混在一起造出来的词。
真正能影响移动端滑动流畅度的 CSS 属性,只有这几个,且各自职责分明:
overscroll-behavior 只管“边界是否穿透”,不管“顺不顺”
- 它解决的是:弹窗滑到底了,再往上拖,背后页面会不会跟着动
- 加了
overscroll-behavior: contain,弹窗不穿透了,但手指一松就停——这不是它的问题,是惯性没激活 - 它对滚动帧率、硬件加速、动能维持零影响
- 常见失效原因:
-
overflow-y没显式设为auto或scroll(仅靠内容溢出不触发滚动上下文) - 父容器是 Flex 布局但没加
min-height: 0,导致子滚动区高度坍缩 - iOS 用
100vh设高,地址栏展开时视口变化,容器高度失准;应改用100dvh(iOS 16.4+)或 JS fallback
-
scroll-behavior: smooth 只管“跳转是否动画”,不管“拖拽是否跟手”
- 它只对锚点跳转、
element.scrollIntoView()生效,对 touchmove 手势滚动完全无效 - 必须写在
html上才可靠:html { scroll-behavior: smooth; } - iOS Safari ≤15.3 完全不支持;15.4+ 支持但不稳定;微信 X5 WebView 常静默降级
- 即使开了它,
window.scrollTo(0, 200)还是硬跳——必须显式写成window.scrollTo({ top: 200, behavior: 'smooth' })
真正决定“滑动是否流畅”的三要素
-
容器高度确定:必须有明确
height或max-height(100dvh优于100vh),Flex 父项加min-height: 0 -
合成层提示到位:iOS 15+ 推荐
will-change: scroll-position;旧版可试transform: translateZ(0),但别滥用在列表项上 -
事件必须 passive:
el.addEventListener('touchmove', handler, { passive: true })—— 漏掉这一条,iOS 上滚动帧率可能从 60fps 直接掉到 20fps
删掉所有 -webkit-overflow-scrolling: touch。它在 iOS 15.4+/Safari 16+ 中不是“没效果”,而是会唤醒旧滚动线程,引发 fixed 错位、下拉刷新失灵、掉帧——DevTools 里搜出来就删,还要检查 UI 库是否 JS 动态注入。
最后提醒一句:没有“一键平滑”的魔法属性。所谓流畅,是高度、合成提示、事件配置、祖先样式四者协同的结果。任意一环出问题,比如父级加了个 filter: blur(1px),整个滚动容器就会退回到 CPU 渲染,再怎么调参数也没用。
立即学习“前端免费学习笔记(深入)”;


















