记一次 iOS Safari 的诡异 Bug
这个 Bug 折磨了我两天,记录一下,希望能帮到遇到类似问题的人。
现象
有个全屏弹窗,在 iOS Safari 上打开后,滚动到底部,再往上滑,页面内容会”弹”一下,然后底部留白。
更诡异的是,这个 Bug 只在生产环境出现,本地开发环境完全没问题。
排查过程
第一天:怀疑样式
首先想到的是 position: fixed 和 100vh 的问题。iOS Safari 的地址栏会收起和展开,导致 100vh 计算不准确。
试了网上常见的方案:
.modal {
height: 100vh;
height: -webkit-fill-available;
}
没用。
又试了用 JS 计算:
const vh = window.innerHeight * 0.01;
document.documentElement.style.setProperty('--vh', `${vh}px`);
还是不行。
第二天:怀疑渲染
开始怀疑是不是 React 的渲染问题。加了 key 强制重渲染,没用。
然后我在本地模拟生产环境打包,发现问题复现了。原来是生产环境的压缩或者某些配置导致的。
进一步排查,发现是 overscroll-behavior 的锅。我们在全局样式里写了:
html {
overscroll-behavior: none;
}
iOS Safari 对这个属性的处理有问题,导致滚动行为异常。
解决方案
.modal {
position: fixed;
inset: 0;
overflow: hidden;
overscroll-behavior: contain;
-webkit-overflow-scrolling: touch;
}
.modal-content {
height: 100%;
overflow-y: auto;
overscroll-behavior: contain;
}
关键点是把 overscroll-behavior: contain 加到弹窗内容上,而不是全局。
教训
- iOS Safari 的怪 Bug 很多,遇到问题先查兼容性
- 生产环境和开发环境的差异要重视
- 有些 CSS 属性看着有用,实际可能引入新问题
另外推荐个网站:can I use,查兼容性必备。还有 WebKit Bugzilla,遇到怪问题可以去搜搜看是不是已知 Bug。
最后吐槽一句:移动端 Web 开发太痛苦了,每个浏览器都有自己的脾气。