Mobile Safari 15底部导航收起时打开模态框底部残留空白如何解决
解决方案
方案1:替换body固定的锁滚动方案
给body设置position: fixed是触发该问题的核心原因,建议换用以下更兼容的锁滚动逻辑:
- 模态框打开时:
- 记录当前页面滚动位置
const scrollY = window.pageYOffset - 给body设置样式:
overflow: hidden,同时添加样式position: relative - 监听
touchmove事件,仅当事件触发源不是模态框内部可滚动区域时,阻止默认行为,避免页面滚动
- 记录当前页面滚动位置
- 模态框关闭时:
- 移除body的
overflow: hidden样式 - 恢复页面滚动位置
window.scrollTo(0, scrollY) - 解绑
touchmove监听事件
- 移除body的
方案2:保留body固定逻辑,适配Safari动态视口
如果必须使用position: fixed的锁滚动方案,做以下适配:
- 用动态视口单位
dvh替代传统vh或百分比高度,Safari 15+已支持该单位,1dvh会实时匹配浏览器当前实际视口高度,自动适配底部导航栏的收起/展开状态:
body.modal-open { position: fixed; top: 0; left: 0; width: 100%; /* 高度用动态视口高度,兼容安全区域 */ height: calc(100dvh + env(safe-area-inset-bottom)); }
- 模态框打开时主动触发一次视口重计算,避免Safari缓存旧的视口高度:
// 模态框打开逻辑执行后,主动触发重绘 window.requestAnimationFrame(() => { document.body.style.height = `${window.innerHeight}px` })
方案3:单独适配模态框定位
不依赖父元素的定位属性,直接给模态框设置独立的定位规则:
.modal { position: fixed; top: 0; left: 0; right: 0; bottom: 0; /* 优先用动态视口高度 */ height: 100dvh; overflow: auto; -webkit-overflow-scrolling: touch; }
内容的提问来源于stack exchange,提问作者Song
相关产品推荐
相关产品推荐

