欢迎关注我的公众号:前端侦探
Safari真不愧是新时代的IE。由于 iOS 26最近发布,一下子把我的页面搞乱了
一、定位错乱问题
比如这样一个上下fixed定位布局
<header>头部</header>
<div class="list">
<div class="item"></div>
<input placeholder="请输入">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<footer>底部</footer>
相关样式如下
header{
position: fixed;
top: 0;
left:0;
right:0;
background: pink;
padding: 10px;
padding-top:padding-bottom: calc(env(safe-area-inset-top) + 10px);
}
footer{
position: fixed;
bottom: 0;
left:0;
right:0;
background: orange;
padding: 10px;
color: #fff;
padding-bottom: calc(env(safe-area-inset-bottom) + 10px)
}
正常情况下没什么问题,上下的吸顶(底)的
但是当呼出键盘后,再次滚动页面,上下定位就出现了偏差
很明显,上下本该贴近屏幕边缘的fixed元素居然错乱了,看着像是整体向上偏移了,导致顶部移出屏幕了,底部漏出一个缝隙。
如果大家手头有iOS 26设备,可以访问这个demo自己体验一下
xboxyan.codelabo.cn/source/ios2…
或者直接扫码体验
为了验证这个不是特例,特意去看了苹果官网,只要有输入框的,触发以后也会出现这种现象(顶部的导航栏往上偏移了)
目前在苹果开发者平台已经看到有相关反馈了,看看什么时候可以修复吧。
developer.apple.com/forums/thre…
那么,在苹果修复之前,有什么办法可以规避这个问题呢?
二、使用容器滚动来代替页面滚动
其实在之前就有这种感觉,safari的页面滚动很容易受到系统行为的影响,给人一种不可靠的感觉,每次系统更新都得看下当前页面是否受影响。
这次的问题也是这样,不知道苹果的底层对webview做了什么特殊优化,导致键盘弹起后整体页面布局出现了偏差。所以这里的解决方式就是使用容器滚动而不是默认的页面滚动。
拿上面的例子来说,最简单的方式是直接嵌套一层
<div class="page">
</div>
然后设置容器滚动
html,body,.page {
margin: 0;
height: 100%;
}
.page {
overflow: auto;
overscroll-behavior: none; /*阻止默认滚动行为*/
}
为了彻底消除系统滚动影响,还可以加上overscroll-behavior: none;,这个属性可以阻止系统的默认滚动行为,比如iOS上的默认回弹效果,滚动联动效果
之前在这篇文章中有详细介绍: 两分钟小技巧!如何阻止 macOS 的触底弹性滚动和双指手势导航
这样这个页面就只有容器滚动了,根本不会触发页面滚动那些乱七八糟的系统行为了。
你可以访问这个demo
xboxyan.codelabo.cn/source/ios2…
或者直接扫码体验
这样问题基本就解决了
三、对现有页面的影响
当然如果是一个已经存在的项目,仅仅以上改动还不够,布局可能没问题了,但是还有一些其他问题。比如有些逻辑是依赖页面滚动的,比如上拉加载,可能之前是通过监听页面滚动实现的,这里要统一改成容器监听
window.addEventListener('scroll', () => {})
// 改为
document.getElementById('#app').addEventListener('scroll', () => {})
然后滚动位置的获取也要改变
document.scrollingElement.scrollTop
//改为
document.getElementById('#app').scrollTop
如果之前在写这些计算逻辑时考虑到了滚动容器,那么这个改动适配就很轻松,否则就有点麻烦了。
四、iframe好像也行?
如果页面要修改的地方太多了,各种滚动计算,或者依赖的第三方库根本就不支持容器滚动,还可以试试iframe容器,结构很简单
<style>
html,body,iframe{
margin:0;
height: 100%;
width: 100%;
border:0;
overflow: hidden;
overscroll-behavior: none;
}
</style>
<body>
<iframe src="./index.html"></iframe>
</body>
这样就是一个最简单的结构了,其实也相当于变相去掉了页面滚动,iframe里的页面滚动系统可不认。
你可以访问这个demo
xboxyan.codelabo.cn/source/ios2…
或者直接扫码体验
当然实际项目中可能还有各种参数,需要一一传递过来,然后还有iframe的性能一直是个问题,加载比较慢,适合一定要解决这个问题又不想大改的场景。
五、希望尽快修复吧
移动端80%的问题都来源于safari,真的是毫无办法,别的不说了,尽快修复吧。最后,如果觉得还不错,对你有帮助的话,欢迎点赞、收藏、转发 ❤❤❤