iOS15 Safari底部地址栏场景下position:fixed可编辑div聚焦遮挡求解
解决方案
这个问题的核心是iOS15+ Safari软键盘唤起时,默认的window视口高度计算不会自动扣除软键盘高度,position: fixed元素的定位基准仍为原始视口,同时浏览器默认的输入框滚动对齐逻辑存在误差,才会出现元素显示不全、底部留白的问题。你之前尝试的方案均针对安全区适配,不覆盖软键盘场景的适配需求。
实现步骤
- 使用VisualViewport API获取真实可视区域参数
iOS15+已经支持VisualViewport API,通过该API可以拿到软键盘唤起后实际的可视区域高度、偏移量,以此为基准调整底部fixed元素的bottom值。 - 禁用页面默认滚动偏移,手动控制滚动位置
软键盘唤起时Safari会自动给页面加滚动偏移,这是底部出现空白的主要原因,需要阻止默认行为后手动对齐滚动位置。 - blur时恢复元素默认定位和页面滚动
代码示例
CSS部分
/* 底部输入框基础样式 */ .input-box { position: fixed; bottom: 0; left: 0; width: 100%; min-height: 44px; padding: 8px 12px; box-sizing: border-box; background: #fff; border-top: 1px solid #eee; /* 关闭默认的touch高亮和自动调整 */ -webkit-tap-highlight-color: transparent; } body { /* 避免默认的滚动回弹导致留白 */ overscroll-behavior: none; }
JS部分
const inputBox = document.querySelector('.input-box'); let originBottom = 0; // 存储原始bottom值,blur时恢复 // 监听输入框聚焦 inputBox.addEventListener('focus', () => { // 监听可视区域变化 window.visualViewport.addEventListener('resize', adjustInputPosition); window.visualViewport.addEventListener('scroll', adjustInputPosition); adjustInputPosition(); }); // 监听输入框失焦 inputBox.addEventListener('blur', () => { // 恢复原始样式 inputBox.style.bottom = `${originBottom}px`; // 移除监听避免内存泄漏 window.visualViewport.removeEventListener('resize', adjustInputPosition); window.visualViewport.removeEventListener('scroll', adjustInputPosition); // 恢复页面滚动位置 window.scrollTo(0, 0); }); function adjustInputPosition() { const viewport = window.visualViewport; // 计算输入框需要偏移的bottom值:原始视口高度 - 可视区域底部偏移 - 输入框自身高度 const offset = window.innerHeight - (viewport.offsetTop + viewport.height); // 调整输入框位置,避免被键盘遮挡 inputBox.style.bottom = `${offset}px`; // 手动调整页面滚动位置,消除底部空白 if (document.documentElement.scrollTop > 0) { document.documentElement.scrollTop = 0; } }
额外适配注意点
- 如果输入框有动态高度变化(比如多行输入),需要在高度变化时主动调用
adjustInputPosition重新计算位置 - 不要额外设置
scroll-padding-bottom相关属性,避免和手动计算的偏移冲突
内容的提问来源于stack exchange,提问作者labu77
相关产品推荐
相关产品推荐

